Immutability makes it easier to parallelize the program
References to immutable objects can be cached as they not going to change
Read-inly properties
class BlaBla {
val oneTime = calculate() // once during class instantiation calculate() is executed
val eachTime: Int
get() = calculate() // !!each time calculate() executes for eachTime access
val name: String? = "Alex"
val secondName: String = "Mart"
val fullName: String?
get() = name?.let {"$it $secondName"}
val fullName2 = name?.let {"$it $secondName"}
fun calculate(): Int {
println("Calculating...")
return 42
}
}
fun main() {
val instance = BlaBla()
if (instance.fullName != null) {
println(instance.fullName?.length) // smartcast doesn't work here as
} // fullName has custom getter
// it means compiler still assumes instance.fullName can be null
if (instance.fullName2 != null) { // smartcast works here
println(instance.fullName2.length)
}
}
Mutable and read-only collections
Down-casting read-only collections to mutable should never take place
Instead do this
val list = listOf(1,2,3)
val mutableList = list.toMutableList()
mutableList.add(4)
Copy in data classes
class User(
val name: String,
val surname: String
) {
fun withSurname(surname: String) = User(name, surname) // each time new object is cretaed
// but this is immutale, which is good
// on the other hand it is too much to create such function for each class field
}
data class User(
val name: String,
val surname: String
)
var user = User("Alex", "Mart")
user = user.copy(surname = "other")
// copy function which comes out of the box for data classes is recommended way to
// keep objects immutable, instead of making fields var