【问题标题】:Swift: converting between Arrays of 'Protocol' and Arrays of implementing ClassSwift:在“协议”数组和实现类数组之间转换
【发布时间】:2015-06-08 09:03:58
【问题描述】:

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

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 中进行这项作业的正确方法是什么?

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

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

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

【问题讨论】:

  • 设法重现您的问题。这看起来很像一个错误:-/ 通过classArr.map{$0 as MyProtocol} 手动转换可能是一种解决方法。

标签: ios arrays swift generics


【解决方案1】:

您可以使用 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}

【讨论】:

    【解决方案2】:

    试试这个

    @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] 
    

    【讨论】:

    • classArr 是故意的[MyClass] 类型。我不想将其重新定义为[MyProtocol]。实际代码要复杂得多,我只提炼出导致问题的部分(恕我直言,这与上下文无关)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多