为什么我不能在self是类的协议扩展中更改变量?

道伊

我很好奇为什么这行不通:

public protocol MyProtocol {
    var i: Int { get set }
}

public protocol MyProtocol2: class, MyProtocol {}

public extension MyProtocol2 where Self: AnyObject {
    func a() {
        i = 0 <-- error
    }
}

错误:

无法分配给属性:“自身”是不可变的

为什么?只有类可以采用MyProtocol2。如果我: class在MyProtocol后面添加声明,它将起作用。我不明白为什么它在子协议上不起作用。

哈米什

您的示例无法编译,因为MyProtocol它不是类绑定的,因此可以具有mutating需求和扩展成员。这包括属性设置器,默认情况下为mutating这样的成员可以自由地将一个全新的重新分配self,这意味着编译器需要确保在可变变量上调用它们。

例如,考虑:

public protocol MyProtocol {
  init()
  var i: Int { get set } // implicitly `{ get mutating set }`
}

extension MyProtocol {
  var i: Int {
    get { return 0 }
    // implicitly `mutating set`
    set { self = type(of: self).init() } // assign a completely new instance to `self`.
  }
}

public protocol MyProtocol2 : class, MyProtocol {}

public extension MyProtocol2 where Self : AnyObject {
  func a() {
    i = 0 // error: Cannot assign to property: 'self' is immutable
  }
}

final class C : MyProtocol2 {
  init() {}
}

let c = C()
c.a()

如果这是合法的,则调用c.a()会将的全新实例重新分配C给该变量c但是c是不可变的,因此代码格式不正确。

使MyProtocol类绑定(即protocol MyProtocol : AnyObject弃用拼写protocol MyProtocol : class)可行,因为现在编译器知道只有类才能符合MyProtocol因此,它通过禁止mutating需求和扩展成员来强加引用语义,从而防止的任何突变self

您可以使用的另一种选择是将需求的设置者标记inonmutating–因此,这意味着只能由不变的设置者来满足。这使您的代码再次格式正确:

public protocol MyProtocol {
  init()
  var i: Int { get nonmutating set }
}

public protocol MyProtocol2 : class, MyProtocol {}

public extension MyProtocol2 where Self : AnyObject {
  func a() {
    i = 0 // legal
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么我不能在Swift中使用let in协议?

为什么我不能在Python中更改类的属性

为什么我不能在变量中捕获FakeItEasy期望?

为什么我不能在addEventListener中调用类函数

为什么我不能在代码中删除中间变量?

为什么我不能在Range扩展中自我循环?

为什么我不能在SQLite中更改值?

为什么我不能在类的不同行中声明和定义成员变量?

为什么我不能在协议中声明动态变量

为什么我不能在React类组件中创建变量?

为什么我不能在Timer.scheduledTimer函数中更改变量的值?

为什么我不能在React中更改输入值?

为什么我不能在Flow API Subscriber中从onComplete访问类变量

为什么我不能在KDE中扩展我的桌面12.04?

为什么我不能在PHP中为类变量定义连接字符串?

C#-为什么我不能在另一个类中更改我的int变量?

为什么我不能在班级中访问变量。Python

为什么我们不能在扩展类的静态方法中使用此实例?

为什么不能在函数内使用kwargs更改变量?

为什么我不能在Notepad ++中更改文本背景

为什么不能在模块中扩展Fixnum类并使用它?

为什么不能在Ruby的单例类定义中访问类实例变量?

为什么我不能在扩展通用特征的类中调用带有参数“ this”的方法?

为什么我不能在if-then语句中更改变量的值?

为什么我不能在定义中定义变量?

为什么我不能在返回 const 的 bool 函数中为类成员变量赋值?C++

为什么我不能在任何方法之外修改类成员变量?

我的全局不能在类的定义中改变

为什么我不能更改变量的值?