协议:无法分配给' X'在' Y'在斯威夫特

时间:2014-06-22 19:13:50

标签: swift protocols

我刚刚定义了一个非常简单的协议和一个使用泛型的类,它可以处理这个协议。

在标有错误的行中,您会收到错误:“无法在'aObj'中分配给'flag'。

 protocol Flag {
    var flag: Bool {get set}
 }


 class TestFlag<T: Flag>  {

    func toggle(aObj: T) {

        if aObj.flag {
            aObj.flag = false;  // <--- error
        } else {
            aObj.flag = true;   // <--- error
        }
    }
 }

你知道为什么以及为了解决这个问题需要改变什么?

2 个答案:

答案 0 :(得分:6)

来自docs

  

默认情况下,函数参数是常量。试图改变   函数体内函数参数的值   导致编译时错误。这意味着你无法改变   错误的参数值。

在这种情况下,您可以添加inout,以便在函数调用之外保留切换:

func toggle(inout aObj: T) {           
   if aObj.flag {
      aObj.flag = false;
   else {
      aObj.flag = true;
   }
}

你也可以做到:

func toggle(var aObj: T) { 
}

但这可能达不到你想要的效果。

答案 1 :(得分:2)

manojlds的回答是正确的,因此我接受了。

然而,几天前有一个类似的答案,使用相同的解决方案,但有其他论证(似乎现在已删除)。

论证是关于compliler无法知道协议是用于类,结构还是枚举。使用Swift,协议可以应用于所有这些类型。但结构实例使用按值调用,对于类实例(对象),我们使用按引用调用。

从我的角度来看,这个答案也是正确的,因为你可以通过第二个解决方案解决问题:

@objc  
protocol Flag {
    var flag: Bool {get set} 
}

只需在协议上添加@obj attriute即可。因此,您只能将此协议用于导致结果的类,只允许通过引用调用。因此,编译器不再需要inout信息。

但我搜索了一个解决方案,以增加协议的重用,并立即使用manojlds建议。