O que é uma fatia em Swift e como ela difere de uma matriz?
A partir da documentação, a assinatura de tipo de subscrito (intervalo) é:
subscript(Range<Int>) -> Slice<T>
Por que não devolver outro em Array<T>
vez de um Slice<T>
?
Parece que posso concatenar uma fatia com uma matriz:
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
Mas isso produz o erro:
não foi possível encontrar uma sobrecarga para 'subscrito' que aceita os argumentos fornecidos
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
O que é uma fatia?
Nota: Felizmente, esta resposta é inválida no Swift beta 3, uma vez que os arrays agora são tipos de valor verdadeiros.
@matt está correto, acima - os
Slice<T>
pontos na matriz. Isso parece contrário à maneira como o Swift lida com todos os outros tipos de dados com os quais estamos trabalhando, pois significa que o valor da fatia pode mudar mesmo se for declarado como uma constante:var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] let slice = arr[0..2] // ["hello", "world"] arr[0] = "bonjour" println(slice) // ["bonjour", "world"]
A pior parte é que a fatia age exatamente como um array. Dado que em Swift temos uma expectativa de imutabilidade, parece perigoso que os valores subscritos da fatia possam mudar sem aviso:
println(slice[1]) // "world" arr[1] = "le monde" println(slice[1]) // "le monde"
Mas se a matriz subjacente muda muito drasticamente, eles são desengatados:
arr.removeAtIndex(0) // this detaches slice from arr println(slice) // ["bonjour", "le monde"] arr[0] = "hola" println(slice) // ["bonjour", "le monde"]
fonte
let arr = ["hello", "world", "goodbye"]; arr[0] = "bonjour"
. Você verá que funciona. Estranhamente, com arrays imutáveis, é apenas o tamanho que é imutável, não o conteúdo. (Veja "Mutabilidade de coleções" na linguagem de programação Swift )Resumo:
As respostas acima eram verdadeiras até o Beta 3 (e podem mudar novamente em versões futuras)
O Slice agora atua como um array, mas como @matt disse acima, é efetivamente uma cópia superficial para um array por baixo do capô, até que uma alteração seja feita. Slices (agora) veja um instantâneo dos valores originais,
Observe também que a sintaxe da fatia mudou:
Exemplo:
var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] var arrCopy = arr let slice = arr[0..<2] // ["hello", "world"] arr[0] = "bonjour" arr // ["bonjour", "world", "goodbye"] arrCopy // ["hello", "world", "goodbye"] slice // ["hello", "world"]
Isso permite um processamento muito mais uniforme, pois é mais simples (IMHO) fazer o processamento de listas no estilo python - filtrando uma lista para fazer outra. de acordo com a resposta de Matt antes do Beta 3, você tinha que criar uma matriz temporária para mapear uma fatia. O novo código agora é mais simples:
class NameNumber { var name:String = "" var number:Int = 0 init (name:String, number:Int) { self.name = name self.number = number } } var number = 1 let names = ["Alan", "Bob", "Cory", "David"] let foo = names[0..<2].map { n in NameNumber(name:n, number:number++) } foo // [{name "Alan" number 1}, {name "Bob" number 2}]
(embora para ser justo, foo ainda é uma fatia)
Referência:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf
Alterações importantes, problemas resolvidos, - linguagem rápida, parágrafo 1
"Array em Swift foi completamente redesenhado para ter uma semântica de valor total, como Dicionário e String ... m"
fonte