What does it mean to have a property that is a val...
# getting-started
s
What does it mean to have a property that is a val (not var) with a get() function attached, and no set() function. It kind of seems like a contraction of terms to have a "val" that changes every time you "get" it. Will the get be called each time or is it gotten once and then reused?
s
Will the get be called each time or is it gotten once and then reused?
It will perform the logic in the getter each time it’s invoked. You can implement a sort of lazy or cached
val
in the getter, or you can have it execute a bunch of logic and return a potentially different value each time, though this is imo bad practice and I’d definitely flag it during code review lol
val
s with open/custom getters are treated specially by the compiler if their return type is nullable, specifically you can’t directly smart cast what they return
s
Interesting. I guess still confused why the compiler would not make you classify this as a var instead of a val if it is attached to a custom getter. I guess it is just that it could potentially be returning the same value every time? Is there any reason not to classify it as var if the getter is expected to return something different? I guess we should probably just change this to a method. Yeah that would make a lot more sense...
c
It’s not a
var
because you can’t set a value to it. Even though it computes a value every time, you can’t directly set that property to any specific value. As far as the compiler is concerned, a
val
with
get()
doesn’t even hold data, and it doesn’t even create a backing field for it. It’s basically just a function with different syntax. But like @Shawn said, doing this is probably better solved using something like a
lazy { }
delegate, or moving it to an actual function for better clarity
One good use for this though is to create a read-only view of an internally mutable property
Copy code
class Foo {

    // this property is a list that can be changed, but the list can also be reassigned
    private var mutableBar: MutableList<String> = mutableListOf()
    
    // this makes a read-only property that always returns the current state of mutableBar, not a cached copy of it
    val readOnlyBar: List<String> get() = mutableBar

}
s
I think I get it now. val Just means you can't mutate the property directly as a property by setting it.