Take the example given in the documentation:
struct User {
id int
}
struct Repo {
users []User
}
fn new_repo() Repo {
user := User{id:10}
return Repo {
users: [user]
}
}
fn (r Repo) find_user_by_id(id int) User? {
for user in r.users {
if user.id == id {
// V automatically wraps this into an option type
return user
}
}
return error('User $id not found')
}
fn main() {
repo := new_repo()
user := repo.find_user_by_id(10) or { // Option types must be handled by `or` blocks
return // `or` block must end with `return`, `break`, or `continue`
}
println(user.id) // ==> "10"
}
This will simply terminate the program if the user is not found. What if I instead wanted to specify a default value to use in this case? Kotlin handles this very elegantly, in my opinion, with the Elvis operator:
fn main() {
repo := new_repo()
user := repo.find_user_by_id(99999) ?: User{id: 5}
println(user.id) // ==> "5"
}
Another way I could see implementing this is through the or block:
fn main() {
repo := new_repo()
user := repo.find_user_by_id(99999) or {
User{id: 5}
}
println(user.id) // ==> "5"
}
I think something like this might be a very valuable addition.
Yes, I thought about this. Most likely the second option will be implemented:
user := repo.find_user_by_id(99999) or {
User{id: 5}
}
As the block just contains an expression, not statement(s), why not make or an expression instead:
user := repo.find_user_by_id(99999) or User{id: 5}
As the block just contains an expression, not statement(s)
Alex explained for if expressions that the block can contain statements too, so I think or {st; value} is best for consistency.
This has been implemented: x := opt() or { 10 }
Most helpful comment
Yes, I thought about this. Most likely the second option will be implemented: