(我用kotlin 1.1.2-2)
我发现有两种方法来定义属性是可变的但不能通过=
分配。
var
私人二手val
具有私有变量支持属性我也发现他们有不同的行为。
当声明T
out
时,无法定义具有私有设置器的var
类型的T
,而具有支持属性的val
是合法的。
open class A<out T>(v: T) {
// error because T occurs in invariant position
var prop1: T = v
private set
private var _prop: T = v
val prop2: T get() = _prop
}
为什么prop1
是不变位置而prop2
不是?差异来自哪里?
答案 0 :(得分:2)
在您的情况下,您宣布private var
可行的方法是,您无法将其更改为A
类,因为它是private
,您可以&#39;} t声明一个带有out variance
参数的函数用于修改目的。
private var
和private set
之间的差异是private
变量,而getter / setter只是在java中生成了一个字段。但private set
属性具有getter / setter,而setter为private
。
out
方差仅适用于读取模式,这意味着您无法在其中添加任何内容。它的实际类型是T
的子类型,或者是java中的? extends T
。
对于out
方差的写入模式相当于Nothing
,因此您根本无法声明setter
/ mutable变量。但您可以使用不可变属性引用它,例如:
open class A<out T>(v: T) {
//v--- immutable
val prop1: T = v
}
如果你能做到,kotin generic就是一件坏事。为什么?根据定义,out T
是T
的子类型,但您尝试将超类型实例T
分配给? extends T
的子类型,例如:
val subInt:A<Int> = A(1);
// v--- Int
subInt.prop1 = 1; // you try to assign an Int to its subtype
// ^--- prop1 is a subtype of Int
以下示例可能会让您更清楚地了解为什么无法在out
方差参数中添加任何内容。
val int: A<Int> = A(1) // ok
val number: A<Number> = int; //ok
number._prop = 1.0;
// ^
//if you can define setter/mutable variable, you try to assign a Double into a Int