Reputation: 335
I'm studying kotlin language and I can't distinguish these examples, especially nullable types in a 'where' clause of generic. Would you tell me the difference?
case 1
class Foo<T> where T: Comparable<T>
class Foo<T> where T: Comparable<T?>
class Foo<T> where T: Comparable<T>?
class Foo<T> where T: Comparable<T?>?
case 2
class Foo<T> where T: Comparable<T>? {
// If a class is declared like above, is a type 'T' already nullable?
// Then,
fun bar(value: T?) { // Should I declare a member function like this to accept null or
// do something
}
fun bar(value: T) { // Should I declare like this instead?
}
}
Upvotes: 2
Views: 69
Reputation: 7738
First, to distinguish T : Comparable<T>
and T : Comparable<T?>
, take a look at the following example. The difference is whether you can compare T
with T?
.
class Bar1(var bar : Int) : Comparable<Bar1>{
override fun compareTo(other : Bar1) : Int {
return bar - other.bar
}
}
class Bar2(var bar : Int) : Comparable<Bar2?>{
override fun compareTo(other : Bar2?) : Int {
return bar - ( other?.bar ?: 0 )
}
}
fun main(){
println(Bar1(1) > Bar1(2))
val bar2 : Bar2? = Bar2(2)
println(Bar2(1) > bar2)
}
Output:
false
false
The difference is that
val bar1 : Bar1? = Bar1(2)
println(Bar1(1) > bar1)
will not compile. bar1
must be unwrapped
Second, to distinguish class Foo<T> where T: Comparable<T>?
and class Foo<T> where T: Comparable<T>?
, it has nothing to do with comparable. Take a look at the following simplified example.
class Foo1<T>(val t : T) where T : Int{
override fun toString() : String{
return "$t"
}
}
class Foo2<T>(val t : T) where T : Int?{
override fun toString() : String{
return "$t"
}
}
fun main(){
println(Foo1(5))
val i : Int? = 5
println(Foo2(i))
}
Output:
5
5
The difference is that println(Foo1(i))
will not compile. i
must be unwrapped.
Upvotes: 3