在Swift中定义类时,您可以拥有var
属性,这些属性类似于其他OOP语言中的普通字段,还有let
属性,这些属性既是只读的又是不可变的(如{{1}在C ++中)。
然而,有一个Swift相当于C ++的T const * const
吗? (也就是说,字段本身是不可变的,但它指向的对象是可变的)?
以下是我的情景的表示:
T * const
(游乐场链接:https://iswift.org/playground?3jKAiu&v=2)
目前这给了我这个编译错误:
class Foo { let bar: Bar init(bar: Bar) { self.bar = bar } } protocol Bar { var fleem: Int? { get set } } class ConcreteBar : Bar { var fleem: Int? = nil } var foo: Foo = Foo( bar: ConcreteBar() ) foo.bar.fleem = 123
请注意我实际上并未设置Swift:: Error: cannot assign to property: 'bar' is a 'let' constant`
foo.bar.fleem = 123
,我只设置bar
。我不知道为什么编译器抱怨分配给bar.fleem
。
如果我更改bar
以使用此功能:
Foo
...然后编译好了,但后来我失去了class Foo {
var bar: Bar
// ...
始终拥有相同实例的保证。
我知道我也可以将其更改为Foo.bar
:
private(set)
...但class Foo {
public private(set) var bar: Bar
// ...
本身仍然可以自由覆盖Foo
对象引用,使用bar
意味着编译器也不能认为引用也是不可变的,所以可以跳过一些优化。
我正在寻找假设的var
或let mutable
关键字或修饰符。
答案 0 :(得分:1)
默认情况下,协议类型对象具有值值语义。因此,如果变量是let
常数,它们就不可变。
要引入引用语义(并且通过扩展,引用的对象的可变性为let
常量),您需要将协议转换为类协议:
protocol Bar: class {
var fleem: Int? { get set }
}
答案 1 :(得分:1)
您需要将class
属性添加到协议中,以使其符合引用类型:
protocol Bar : class { ...