Travis Griggs
02/05/2020, 12:14 AMclass Slot<T> {
private var _value:T
var value:T
get() = this._value
set(newValue) {
this._value = newValue
// trigger notifications here
}
I wanted to add a variant of the value
interface for types of T
that are Comparable
that would filter out no op changes. So I added the following extension:
var <T : Comparable<T>>Slot<T>.concisely:T
get() = this.value
set(newValue) {
if (this.value != newValue) {
this.value = newValue
}
}
This works like a charm... Slot<Int>(42).concisely = 42
does just what I want. The inner value
doesn't get called.
Where this falls apart is when I have a T
that is an optional. Slot<String?>("foo").concisely = "foo"
won't even compile:
Type for parameter bound T in
var <T : Comparable<T>>Slot<T>.concisely:T
is not satisfied: inferred String? is not a subtype of Comparable<String?>
I have thrown various alternate incantations at my extension to try and accomodate optionals, but nothing seems to work. Is it even doable? What am I missing? I know that I can use ==
on optional types...nils
02/05/2020, 12:30 AMMarat Akhin
02/05/2020, 9:22 AMComparable
for your use-case? !=
is desugared into calls to equals
, not compareTo
Marat Akhin
02/05/2020, 9:43 AMT : Comparable<T>
bound states that T
should be a subtype of a non-nullable type, which can never be true for nullable T
.
If you really do need Comparable
(which is unfortunately contravariant) and also want to support nullable types, you can cheat a little 😃
var <T : Comparable<Q>?, Q : T> Slot<T>.concisely: T
get() = this.value
set(newValue) {
if (this.value != newValue) {
this.value = newValue
}
}
Travis Griggs
02/05/2020, 5:05 PMTravis Griggs
02/05/2020, 5:32 PMTravis Griggs
02/05/2020, 5:33 PMTravis Griggs
02/05/2020, 5:36 PMMarat Akhin
02/05/2020, 5:37 PMAny
which provides equality )))