为什么var与私人二传手是不变的位置?

时间:2017-07-01 05:36:45

标签: types kotlin covariance

(我用kotlin 1.1.2-2)

我发现有两种方法来定义属性是可变的但不能通过=分配。

  1. var私人二手
  2. val具有私有变量支持属性
  3. 我也发现他们有不同的行为。

    当声明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不是?差异来自哪里?

1 个答案:

答案 0 :(得分:2)

在您的情况下,您宣布private var可行的方法是,您无法将其更改为A类,因为它是private,您可以&#39;} t声明一个带有out variance参数的函数用于修改目的。

private varprivate 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 TT的子类型,但您尝试将超类型实例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