繁体   English   中英

Swift:在'Protocol'和实现Class的数组之间进行转换

[英]Swift: converting between Arrays of 'Protocol' and Arrays of implementing Class

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

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中进行此分配的正确方法是什么?

PS有趣的是,当使用基类而不是协议时, 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}

试试这个

@objc protocol MyProtocol {
    var x: Int { get }
}

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

如果使用@objc,两者都有效

 var classArr: [MyClass] = [MyClass(), MyClass()]     
 var protocolArrA: [MyProtocol] = classArr
 var protocolArrB: [MyProtocol] = classArr as [MyProtocol] 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM