Swift

时间:2017-03-09 04:59:33

标签: swift oop

在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意味着编译器也不能认为引用也是不可变的,所以可以跳过一些优化。

我正在寻找假设的varlet mutable关键字或修饰符。

2 个答案:

答案 0 :(得分:1)

默认情况下,协议类型对象具有值值语义。因此,如果变量是let常数,它们就不可变。

要引入引用语义(并且通过扩展,引用的对象的可变性为let常量),您需要将协议转换为类协议:

protocol Bar: class {
    var fleem: Int? { get set }
}

答案 1 :(得分:1)

您需要将class属性添加到协议中,以使其符合引用类型:

protocol Bar : class { ...