gpt4 book ai didi

swift - 在非类绑定(bind)协议(protocol)的扩展中,实例必须被视为值类型

转载 作者:搜寻专家 更新时间:2023-11-01 05:32:48 25 4
gpt4 key购买 nike

代码如下:

protocol A {
var a: Int { get set }
}

extension A {
var convenientAccessor: Int {
get { return a }
set { a = newValue }
}
}

class B: A {
var a: Int = 0
}

func acceptsB (instance: B) {
instance.a = 1 // This compiles
instance.convenientAccessor = 2 // This does not
}

我有点理解这里的问题,但我真的很想得到更深入理解它的人的回答,更重要的是我的问题的解决方法,即我想传递已知的类类型并能够使用方便的访问器,而不会被我使用值类型的可能性所抑制。在我的例子中,定义这些方便的访问器的协议(protocol)不应该是类绑定(bind)的(它们对于值类型是完全有效和有用的),所以虽然这在技术上是一种解决方法,但我并不满意。

最佳答案

让我们从一个总结开始:convenientAccessor 是一个可写属性,因此对它的任何赋值都会导致突变。这种突变发生在您的函数内部。

问题在于,当使用 convenientAccessor 属性时,编译器将 instance 视为协议(protocol) A,并且因为函数的参数是 let,它不允许对它们进行修改,因为此时协议(protocol)也可以通过值类型实现。

我想到的两个解决方案是:

  1. 将协议(protocol) A 限制为仅类:

    protocol A: class 

    这会通知编译器只有类才能符合协议(protocol),这允许对任何类型的变量(letvar)进行修改

    <
  2. 使函数参数inout:

    func acceptsB (instance: inout B)

    这会创建一个“写入漏洞”,因为现在 instance 是可写的,所以对它的任何更改都会传播回上游,即使 B 是一个值类型。

就个人而言,如果您计划只使用类,我会选择 #1,正如您在问题中提到的那样。

关于swift - 在非类绑定(bind)协议(protocol)的扩展中,实例必须被视为值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52417947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com