提问者:小点点

Swift中的切片是什么?


Swift中的切片是什么?它与数组有何不同?

从文档中可以看出,下标(范围)的类型签名是:

subscript(Range<Int>) -> 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]

什么是切片?


共3个答案

匿名用户

切片指向数组。当数组已经存在并且切片只能描述所需的部分时,创建另一个数组是没有意义的。

加法会导致隐含的强制,因此起作用。要使你的任务发挥作用,你需要强迫:

var list = ["hello", "world"]
var slice: Array<String> = Array(list[0..<list.count])

匿名用户

注意:这个答案很高兴在Swift beta 3中是无效的,因为数组现在是真值类型。

@matt是正确的,上面-指向数组。这似乎与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"]

匿名用户

上面的答案在Beta 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"]

这允许更统一的处理,因为执行python样式的列表处理更简单(IMHO)--过滤一个列表以生成另一个列表。根据Matt在Beta3之前的回答,您必须创建一个临时数组来映射一个切片。新代码现在更简单了:

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}]

(虽然公平地说,傅仍然是一个切片)

http://adcdownload.apple.com//developer_tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf

重要的变化,已解决的问题,-快速的语言,第1段

“Swift中的数组已完全重新设计,具有完整的值语义,如字典和字符串...m”