web-dev-qa-db-ja.com

Swiftのスライスとは何ですか?

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]

スライスとは何ですか?

85
hjing

スライスは配列を指しています。配列が既に存在する場合、別の配列を作成しても意味がなく、スライスは必要な部分だけを記述できます。

追加により暗黙の強制が発生するため、機能します。割り当てを機能させるには、yoに強制する必要があります。

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

注:配列は真の値型であるため、Swift beta 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"]
22
Nate Cook

概要:

上記の回答は、ベータ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)になるため、より均一な処理が可能になります。 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はまだスライスです)

参照:

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

重要な変更、解決された問題-Swift言語、段落1

「Swiftの配列は、DictionaryやString ... mなどの完全な値セマンティクスを持つように完全に再設計されました。」

14
Chris Conover