i dont want to make the `instance` nullable, i jus...
# announcements
p
i dont want to make the
instance
nullable, i just want
simpleName
to return
""
in that case.. but even wrapping it in
if (instance != null)
does not help
s
try bounding
R
as
Any
-
Copy code
class Wrapper<R : Any>(private val instance: R? = null)
❤️ 1
p
hmm.. that helped.. that is very interesting.. if i dont specify a bound its
Any?
by default?
s
yep
s
But
instance
is a
R?
, it still can be null…
p
i guess i am confused as to what
R?
exactly does..
yup, Anton, it wont compile with just that one change
but it will let you do an null check and smart cast it
👆 1
it will also let you do
!!
s
So there’s a subtle thing you gotta take into account here as far as the parameterization of the class goes
s
Copy code
class Wrapper<R : Any>(private val instance: R? = null){
    fun simpleName() = instance?.let { it::class.simpleName }  // no more error on this line
}
s
Without
<R : Any>
, it’s possible to have a valid wrapper of both
Wrapper<Foo>
and
Wrapper<Foo?>
@streetsofboston
fun simpleName() = if (instance != null) instance::class.simpleName else ""
seems to work just fine
s
That’s true…it’s a
val
, not a `var`…
s
A wrapper that can hold a
Foo
but actually holds
null
is perfectly valid - it’s kinda how Optional works
p
i see that nullable types bring some new complexity into generics
s
yep
s
If you want to prevent null values for
instance
do
class Wrapper<R : Any>(private val instance: R)
s
No, but, sometimes you do want null values
p
yup. in my case i do want instance to be sometimes null
s
In this case I think @poohbar wants this Wrapper to be able to hold null in certain cases, but you don’t want the type to be
Wrapper<Foo?>
, you want it to be
Wrapper<Foo>
, much like
Optional<Foo>
if you’ve used that at all in Java-land
smart-casting breaks because if
R
itself is a nullable type, then there is no way to safely dereference it
☝️ 1
s
Then, what @Shawn suggested is the best way to go:
class Wrapper<R : Any>(private val instance: R? = null)
p
yup.. i must admit that I still find it a bit confusing that an
Optional<Foo>
can hold
null
🤔
i guess it's ok though.. since the accessor method clearly returns
Foo?
makes sense..
thanks guys 🙂
👍 1
s
It’s a bit weird: Take this:
Copy code
class Wrapper<R>(private val instance: R?){
    fun simpleName() = instance?.let { it::class.simpleName }  // error on this line
}
The
it::
has an error about
it
being a nullable type. Event though
instance?.let { }
was called with a
.?
operator,
it
is still nullable. It almost looks like
instance
is
R??
s
R??
isn’t a bad way of putting it actually
Optional<R>
is essentially the only way Java can really express the notion of
R | null
or a union of those two types
if you allowed
R
itself to be nullable you’d have some kind of weird
Union[Union[R, null], null]
s
Alas, it isn’t
R??
, it is actually
R?????????????????????????????????? ....
This still has a nullability error in the compiler:
fun simpleName() = instance?.let { it?.let { it::class.simpleName } }
s
which I don’t think the Kotlin type system handles well