首页 文章

什么是Swift片?

提问于
浏览
86

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

从文档中,下标(Range)的类型签名是:

subscript(Range<Int>) -> Slice<T>

为什么不返回另一个 Array<T> 而不是 Slice<T>

看起来我可以将切片与数组连接起来:

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

但这会产生错误:

找不到接受提供的参数的'下标'的重载

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

什么是切片?

3 回答

  • 14

    切片指向数组 . 当数组已经存在且切片只能描述它的所需部分时,没有必要制作另一个数组 .

    这种加法导致了隐含的强制,因此它起作用 . 要使您的作业有效,您需要强制:

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

    Note: 从Swift beta 3开始,这个答案很快就失效了,因为数组现在是真值类型 .


    @matt是正确的,上面 - Slice<T> 指向数组 . 这似乎与Swift处理我们're working with, since it means the value of the slice can change even if it'声明为常量的所有其他数据类型的方式相反:

    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"]
    
  • 21

    摘要:

    以上答案在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样式列表处理 - 过滤一个列表来制作另一个列表 . 根据Matt在Beta 3之前的答案,您必须创建一个临时数组才能映射切片 . 新代码现在更简单:

    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仍然是一片)

    参考:

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

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

    “Swift中的数组已经完全重新设计,具有完整的语义,如Dictionary和String ...... m”

相关问题