Types 为什么带有私有setter的var是不变位置?
(我使用kotlin 1.1.2-2) 我发现有两种方法可以定义可变但无法通过Types 为什么带有私有setter的var是不变位置?,types,kotlin,covariance,Types,Kotlin,Covariance,(我使用kotlin 1.1.2-2) 我发现有两种方法可以定义可变但无法通过=分配的属性 var与私有setter val带有私有变量支持属性 我还发现他们有不同的行为 当T被声明为out时,不能定义带有私有setter的T类型的var,而带有backing属性的val是合法的 open class A<out T>(v: T) { // error because T occurs in invariant position var prop1: T = v
=
分配的属性
var
与私有setterval
带有私有变量支持属性T
被声明为out
时,不能定义带有私有setter的T
类型的var
,而带有backing属性的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
}
开放式A类(v:T){
//错误,因为T出现在不变位置
变量1:T=v
专用设备
私有var_prop:T=v
val prop2:T get()=\u prop
}
为什么
prop1
是不变位置而prop2
不是不变位置?差异从何而来?在您的案例中,您声明的私有var
可以工作是,您不能将其从类A
中更改,因为它是私有的
,并且您不能为修改目的声明带有输出方差的函数
private var
和private set
之间的区别在于private
变量没有getter/setter,只是在java中生成了一个字段。但是private set
属性具有getter/setter,并且setter是private
out
方差仅适用于读取模式,这意味着您不能在其中添加任何内容。它的实际类型是T
,或?在java中扩展T
因为out
变量的写入模式等同于Nothing
,所以您根本不能声明setter
/mutable变量。但您可以使用不可变属性引用它,例如:
open class A<out T>(v: T) {
//v--- immutable
val prop1: T = v
}
也许下面的示例会让您更清楚地了解为什么不能在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
val int:A=A(1)//确定
val编号:A=int//好啊
数量._prop=1.0;
// ^
//如果可以定义setter/mutable变量,那么可以尝试将Double赋值到Int中
没有getter/setter似乎是一个次要的实现细节,不足以解释类型系统中的差异semantics@voddan是的,先生。事实上,这种行为在kotlin中应该被禁止。没有必要禁止它。Kotlin意识到允许private var prop:T
,其中T
是协变(out
)类型参数可能会导致类型系统冲突,因此这些属性被视为“对此私有”,例如,只允许类在自己的实例上更改它们。@RomanElizarov hi,正如您所说,它可以在自己的实例中更改,因此应该禁止这种行为。假设您有一个可以在内部更改的函数,例如:\u prop=1 as T
,如果T
不是Int
,则代码不可靠。请提供一个自包含的示例,演示由于协变类型的可变属性而导致的类型系统冲突?我看得越久,对我来说,它越像一个bug:/1尝试为prop1变量添加“private get”,然后再次检查。“私有集”可能会添加一个不一致的对象,该对象将在类之外返回。
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