1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

doc: document the Option/Result split

This commit is contained in:
Alexander Medvednikov
2022-10-24 16:11:20 +03:00
committed by GitHub
parent 4aa4af4afb
commit 2c9e890c3d

View File

@@ -3502,7 +3502,12 @@ This is a special case of a [sum type](#sum-types) declaration.
### Option/Result types and error handling ### Option/Result types and error handling
Option types are declared with `?Type`: Optional types are for types which may represent `none`. Result types may represent an error returned from a function.
`Option` types are declared by prepending `?` to the type name: `?Type`.
`Result` types use `!`: `!Type`.
```v ```v
struct User { struct User {
id int id int
@@ -3513,42 +3518,52 @@ struct Repo {
users []User users []User
} }
fn (r Repo) find_user_by_id(id int) ?User { fn (r Repo) find_user_by_id(id int) !User {
for user in r.users { for user in r.users {
if user.id == id { if user.id == id {
// V automatically wraps this into an option type // V automatically wraps this into a result or option type
return user return user
} }
} }
return error('User $id not found') return error('User $id not found')
} }
// A version of the function using an optional
fn (r Repo) find_user_by_id2(id int) ?User {
for user in r.users {
if user.id == id {
return user
}
}
return none
}
fn main() { fn main() {
repo := Repo{ repo := Repo{
users: [User{1, 'Andrew'}, User{2, 'Bob'}, User{10, 'Charles'}] users: [User{1, 'Andrew'}, User{2, 'Bob'}, User{10, 'Charles'}]
} }
user := repo.find_user_by_id(10) or { // Option types must be handled by `or` blocks user := repo.find_user_by_id(10) or { // Option/Result types must be handled by `or` blocks
println(err)
return return
} }
println(user.id) // "10" println(user.id) // "10"
println(user.name) // "Charles" println(user.name) // "Charles"
user2 := repo.find_user_by_id2(10) or { return }
} }
``` ```
V combines `Option` and `Result` into one type, so you don't need to decide which one to use. V used to combine `Option` and `Result` into one type, now they are separate.
The amount of work required to "upgrade" a function to an optional function is minimal; The amount of work required to "upgrade" a function to an optional/result function is minimal;
you have to add a `?` to the return type and return an error when something goes wrong. you have to add a `?` or `!` to the return type and return an error when something goes wrong.
If you don't need to return an error message, you can simply `return none`
(this is a more efficient equivalent of `return error("")`).
This is the primary mechanism for error handling in V. They are still values, like in Go, This is the primary mechanism for error handling in V. They are still values, like in Go,
but the advantage is that errors can't be unhandled, and handling them is a lot less verbose. but the advantage is that errors can't be unhandled, and handling them is a lot less verbose.
Unlike other languages, V does not handle exceptions with `throw/try/catch` blocks. Unlike other languages, V does not handle exceptions with `throw/try/catch` blocks.
`err` is defined inside an `or` block and is set to the string message passed `err` is defined inside an `or` block and is set to the string message passed
to the `error()` function. `err` is empty if `none` was returned. to the `error()` function.
```v oksyntax ```v oksyntax
user := repo.find_user_by_id(7) or { user := repo.find_user_by_id(7) or {