Swift의 슬라이스는 무엇이며 배열과 어떻게 다릅니 까?
문서에서 subscript (Range)의 유형 서명은 다음과 같습니다.
subscript(Range<Int>) -> Slice<T>
Array<T>
대신 다른 것을 반환하지 Slice<T>
않습니까?
슬라이스를 배열과 연결할 수있는 것 같습니다.
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
그러나 이것은 오류를 생성합니다.
제공된 인수를 허용하는 ‘subscript’에 대한 오버로드를 찾을 수 없습니다.
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
슬라이스 란?
답변
슬라이스가 배열을 가리 킵니다. 배열이 이미 존재하고 슬라이스가 원하는 부분을 설명 할 수있는 경우 다른 배열을 만드는 점이 없습니다.
추가는 암시 적 강제를 유발하므로 작동합니다. 과제 작동하려면, 당신은 강제해야합니다 :
var list = ["hello", "world"]
var slice: Array<String> = Array(list[0..<list.count])
답변
참고 : 배열이 이제 진정한 값 유형이기 때문에이 답변은 Swift 베타 3에서 유효하지 않습니다.
@matt가 정확합니다. 위의- Slice<T>
배열에 대한 포인트. 이는 Swift가 작업중인 다른 모든 데이터 유형을 처리하는 방식과 반대되는 것 같습니다. 이는 슬라이스가 상수로 선언 된 경우에도 값이 변경 될 수 있음을 의미하기 때문입니다.
var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"]
let slice = arr[0..2] // ["hello", "world"]
arr[0] = "bonjour"
println(slice) // ["bonjour", "world"]
최악의 부분은 슬라이스가 배열처럼 작동한다는 것입니다. Swift에서 우리는 불변성에 대한 기대를 가지고 있다는 점을 감안할 때 슬라이스의 첨자 값이 경고없이 변경 될 수 있다는 것은 위험 해 보입니다.
println(slice[1]) // "world"
arr[1] = "le monde"
println(slice[1]) // "le monde"
그러나 기본 배열이 너무 급격하게 변경되면 연결이 해제됩니다.
arr.removeAtIndex(0) // this detaches slice from arr
println(slice) // ["bonjour", "le monde"]
arr[0] = "hola"
println(slice) // ["bonjour", "le monde"]
답변
요약:
위의 답변은 베타 3까지 사실입니다 (향후 릴리스에서 다시 변경 될 수 있음).
Slice는 이제 배열처럼 작동하지만 @matt가 위에서 말했듯이 변경이 이루어질 때까지 사실상 내부 배열에 대한 얕은 복사본입니다. 슬라이스 (현재)는 원래 값의 스냅 샷을보고,
또한 슬라이스 구문이 변경되었습니다.
[from..upToButNotIncluding] -> [from..<upToButNotIncluding]
예:
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"]
이것은 파이썬 스타일 목록 처리를 수행하는 것이 더 간단하기 때문에 (IMHO) 훨씬 더 균일 한 처리를 허용합니다. 하나의 목록을 필터링하여 다른 목록을 만듭니다. Beta 3 이전의 Matt의 답변에 따라 슬라이스를 매핑하려면 임시 배열을 만들어야했습니다. 이제 새 코드가 더 간단 해졌습니다.
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}]
(공평하기는하지만, foo는 여전히 슬라이스입니다)
참고:
중요한 변경 사항, 해결 된 문제,-Swift Language, 단락 1
“Swift의 배열은 Dictionary 및 String … m과 같은 완전한 값 의미를 갖도록 완전히 재 설계되었습니다.”