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?
source to share
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
source to share