Why is var with a private setter an invariant position?

(i am using kotlin 1.1.2-2)

I found that there are two ways to define a property that is variable but cannot be assigned via =

.

  • var

    with private installer
  • val

    private variable protected

I also found that they have different behavior.

When T

declared out

, a var

type T

with a private setter cannot be defined, but a type val

with a guard property is legal.

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
}

      

Why prop1

is it an invariant position, but prop2

not? Where does this difference come from?

+3


source to share


1 answer


In your case, you are declaring that the job private var

may be that you cannot change it from the class A

, as it is private

, and you cannot declare a function with a parameter out variance

for modification purposes.

The difference between private var

and private set

is a variable private

that doesn't have a getter / setter, just a generated field in java. but properties private set

have getter / setter and setter private

.

The variance out

is read-only, which means you cannot add anything to it. and its actual type is subtype T

or ? extends T

in java.

For write mode, out

variance is equivalent Nothing

, so you can't declare a setter

/ mutable variable at all . but you can refer to it with an immutable property like:

open class A<out T>(v: T) {
 //v--- immutable
  val prop1: T = v

}

      



If you can do it, common cotin is bad. What for? by definition, it out T

is a subtype T

, but you are trying to assign an instance of a supertype to a T

subtype ? extends T

, for example:

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

      

Perhaps the following example will make you clearer why you can't add anything to the variance parameter 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 

      

+1


source







All Articles