Consider a protocol and a class that implements it:
protocol MyProtocol {
var x: Int { get }
}
class MyClass : MyProtocol {
var x: Int = 5
}
I have an array of type [MyClass]
and I wish to assign it to a variable of type [MyProtocol]
. However, this causes a error when attempted in 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]
What is the correct way to make this assignment in Swift?
P.S. Interestingly, when using a base class instead of a protocol, the expressions for protocolArrA
and protocolArrB
work without error.
It is also interesting to note that assigning a newly created instance of [MyClass] also works well:
var protocolArrD: [MyProtocol] = [MyClass]() // A-OK!
You can use map to cast each element to the desired type:
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}
Note, Swift is able to infer all of the array types above, so this can be written more succinctly as:
var classArr = [MyClass(), MyClass()]
var protocolArrA = classArr.map{$0 as MyProtocol}
var andBack = protocolArrA.map{$0 as! MyClass}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With