ios - Swift: 'Protocol'数组和实现类数组之间的转换

标签 ios arrays swift generics

考虑一个协议(protocol)和一个实现它的类:

protocol MyProtocol {
    var x: Int { get }
}

class MyClass : MyProtocol {
    var x: Int = 5
}

我有一个类型为 [MyClass] 的数组,我希望将它分配给一个类型为 [MyProtocol] 的变量。但是,这会在 Playground(XCode 6.3、Swift 1.2)中尝试时导致错误:

var classArr: [MyClass] = [MyClass(), MyClass()]

var protocolArrA: [MyProtocol] = classArr // Causes error: EXC_BAD_INSTRUCTION
var protocolArrB: [MyProtocol] = classArr as [MyProtocol] // Causes error: EXC_BAD_INSTRUCTION
var protocolArrC: [MyProtocol] = [MyProtocol](classArr) // Causes error: Cannot find an initializer for type [MyProtocol[ that accepts an argument list of type [MyClass]

在 Swift 中进行此赋值的正确方法是什么?

附言有趣的是,当使用基类而不是协议(protocol)时,protocolArrAprotocolArrB 的表达式可以正常工作。

同样有趣的是,分配新创建的 [MyClass] 实例也很有效:

var protocolArrD: [MyProtocol] = [MyClass]()   // A-OK!

最佳答案

您可以使用 map 将每个元素转换为所需的类型:

protocol MyProtocol {
    var x: Int { get }
}

class MyClass : MyProtocol {
    var x: Int = 5
}

var classArr: [MyClass] = [MyClass(), MyClass()]

var protocolArrA:[MyProtocol] = classArr.map{$0 as MyProtocol}
var andBack:[MyClass] = protocolArrA.map{$0 as! MyClass}

请注意,Swift 能够推断出上述所有数组类型,因此可以更简洁地写成:

var classArr = [MyClass(), MyClass()]

var protocolArrA = classArr.map{$0 as MyProtocol}
var andBack = protocolArrA.map{$0 as! MyClass}

关于ios - Swift: 'Protocol'数组和实现类数组之间的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30705045/

相关文章:

ios - Postman - Firebase 通知 ios

ios - 如何根据其在 Swift 中的位置为加扰字母制作动画?

javascript - 如何在 AngularJS 中使用 ng-repeat 循环过滤器?

arrays - Swift 4 替换字符串中的单词

ios - ContiguousArrayStorage 没有实现 methodSignatureForSelector

ios - 当目标是我的 iPhone 5c 时,Xcode 项目不会使用核心数据构建/运行

ios - 从字符串中删除 U\0000fffc unicode 标量

javascript - 如何更改满足特定条件的数组的两个连续值?

swift - 关闭解析推送状态

audio - 在Xcode 6 Swift上插入声音