注意:
我知道那里有很多类似的问题-至少关于“ ArraySlice是什么,我该怎么做?”。我还没有找到一个我都理解的答案,这说明了解决此问题的正确方法(向那些不了解Swift角落的人)。

内容

在像Python这样的语言中,使用数组切片创建新数组是一种常见功能并且可行,但是由于ArraySlice的原因,它并不是那么简单。

考虑以下示例:

struct MyStruct {
    var myValue = 0
    init(value:Int) {
        self.myValue = value
    }
}

var myArray = [MyStruct]()

for i in 0...10 {
    myArray.append(MyStruct(value: i))
}

var myOtherArray: [MyStruct]
myOtherArray = myArray[0...4]


这将引发错误:

Cannot subscript a value of type '[myStruct]' with an index of type 'CountableClosedRange<Int>'

一些类似的问题也将答案与此类型转换相关,并建议:

if let mySlice = myArray[0...4] as? [MyStruct] {
    myOtherArray = mySlice
}


但是这种类型的转换将始终失败。

但是大多数答案给出了更直接的方法:

let mySlice = myArray[0...4]
myOtherArray = Array(mySlice)


在此示例中不会导致错误。

但是,如果我们增加一点复杂度:

class MyClass {
    var array = [MyStruct]()

    init(length: Int) {
        for i in 0...length {
            self.array.append(MyStruct(value: i))
        }
    }

    init(myArray: [MyStruct]){
        self.array = myArray
    }
}

var myInstance = MyClass(length: 10)

myInstance.array[0...4]


var myNewInstance = MyClass(myInstance.array[0...4])仍然会导致错误,但是现在:

let mySlice = myInstance.array[0...4]
var myNewInstance = MyClass(mySlice)


不起作用,并出现缺少可用过载的错误。
是!我可以通过在MyClass中添加以下内容来重载此行为

init(_ myArray: ArraySlice<MyStruct>){
    self.array = Array(myArray)
}


太棒了



有人可以解释一下为什么从子数组中创建一个新数组需要这么多工作吗?特殊的重载声明_ :是什么?

最佳答案

每当您想从Array创建新的ArraySlice时,只需将幻灯片传递到Array的初始化程序中即可:

let sourceArray = [1, 2, 3]
let slice = sourceArray[0...1]
let array = Array(arraySlice)


您在问题中提到自己。我不确定混乱在哪里。在您的特定示例中,您只需执行以下操作:

var myNewInstance = myClass(Array(myInstance.array[0...4]))


现在,解释一下“特殊重载声明_ :”。 _只是用于煽动参数不应包含关键字的令牌。

如果声明如下所示:

init(myArray: ArraySlice<myStruct>)


它会这样称呼:

myClass(myArray: someSlice)


但是myArray关键字没有添加任何有意义的信息,只会使呼叫站点混乱。您可以通过将关键字显式设置为_来删除关键字(默认情况下设置为参数名称):

init(_ myArray: ArraySlice<myStruct>)


被这样称呼:

myClass(someSlice)

10-04 14:25