For a class `X`: ```data class X(val v: String)```...
# announcements
a
For a class `X`:
Copy code
data class X(val v: String)
If this works
X::v
shouldn't this also work
X?::v
?
h
Well no. Because what happens if X is null. You would get an NPE
a
Not really, I'm trying to access the
X?
type itself (the nullable version of
X
), not an instance of it.
🤔 1
image.png
c
You are calling a member reference so the class you want to access the reference on cannot be null. https://kotlinlang.org/docs/reference/reflection.html#function-references
a
I still don't see what can be null here,
A?
is supposed to be as much of a type as
A
, it's just a type that accepts null as an instance of it, which should only matter if I try to get a value of
v
by calling
get
and passing a receiver. I'm trying to get
KProperty1<A?, String>
, which itself should never throw an NPE.
c
the
?
and
::
operator cannot work together as accessing a member reference on a nullable object does not make any sense.
and
A?
is not a type itself
A
is the type and
?
tells that it can be null, which is syntactic sugar in kotlin.
a
A?
is a type, you can defines extension functions with it as a receiver, you can pass it as a type parameter, you can use it as a bound for type parameters, you can define parameters and variables of type
A?
https://kotlinlang.org/spec/type-system.html#nullable-types

https://www.youtube.com/watch?v=juFkdMv4B9s&amp;ab_channel=JetBrainsTV

c
In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type 
String
 can not hold null
https://kotlinlang.org/docs/reference/null-safety.html
but anyway,
::
gives you a reference to a function on a class so the class - not the object - cannot be of an nullable type.
👍 2
n
A? is not A though, it's a super type of A
☝️ 1
So it doesn't have all the same members
It's pretty similar to if you have a base and derived and tried to access a property only defined in derived, through the base type
a
@Nir Yup, I was assuming
A?
would contain the properties declared in class
A
, but I can see why that wouldn't be the case.
c
🙈 okay, live with that answer.
😂 1
a
@Chrimaeon I'm working on a validation framework, where one of the things you can do is define validations on properties of the properties of the class being validated (if that makes sense). So here for example, since
n
is nullable, I need to pass a
KProperty1<Nested?, String>
to be able to validate against
x
@Chrimaeon
🙈 okay, live with that answer.
Sneaky 😂
😂 1
c
So, you mix up type declarations and operators.
Nestes?
in a variable declarations means that the variable is of type
Nested
and can be null. then there is the
?.
operator which is a safe-call operator on such a nullable variable. there is no
?::
operator as referencing a function/property on a
Class
with
::
will give you a reference to the function/property. So the reference is on the class not the declaration with type
Nested?
. you'r
on
function shoudl not care about the parameter
n
of the nullable type I guess.
a
I'm trying to use the
::
operator on the
Nested?
type, assuming
Nested?
contained the properties of
Nested
which doesn't seem like it does. The problem is, the
ValidatorBuilder
of the outer
on
has two type params, one is passed from the
ConstraintBuilder
and one is inferred from the property passed to
on
, so it takes
Password
from the
ConstraintsBuilder
and
Nested?
from the property. The
ValidatorBuilder
of the inner
on
takes its first type param from the
ValidatorBuilder
of the outer
on
which is now
Nested?
and its second type param is inferred from the property passed to it which is
String
. Now since the property being passed to the inner
on
needs to be of type
KProperty<Nested?, String>
, I need to either pass
Nested?::x
or somehow tell Kotlin I need to extract the non-nullable version of the type parameter inferred. You can see the declaration of the inner
on
here: https://github.com/AhmedMourad0/kotlin-validation/blob/nesting_validators/core/src/main/kotlin/dev/ahmedmourad/validation/core/DslBuilders.kt#L[…]86 https://github.com/AhmedMourad0/kotlin-validation/blob/nesting_validators/core/src/main/kotlin/dev/ahmedmourad/validation/core/Descriptors.kt
n
I think you probably need to constrain some things as not nullable in your generic code
At least, that's the simplest
T: Any
Another approach may be to use overloading but I'm not confident how well that would work in kotlin
a
Unfortunately, neither of those seem to work.
n
Not sure I understand then
If the problem is the possibility of T being null
Then constraining T to not be null is a solution
a
T
is used both as nullable and non-nullable, it's used as non-nullable for the
property
parameter, and as nullable for the
validation
method parameter. https://github.com/AhmedMourad0/kotlin-validation/blob/6c401d9ecdc819fc63dee1dc5d7[…]/src/main/kotlin/dev/ahmedmourad/validation/core/DslBuilders.kt
That is when
T
is originally nullable, if it isn't then it should be non-nullable in both locations.