mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
doc: improve types order (#16399)
This commit is contained in:
parent
46f1b20bbc
commit
9a8602ff03
363
doc/docs.md
363
doc/docs.md
@ -113,11 +113,11 @@ To do so, run the command `v up`.
|
||||
<tr><td width=33% valign=top>
|
||||
|
||||
* [Type Declarations](#type-declarations)
|
||||
* [Interfaces](#interfaces)
|
||||
* [Function Types](#function-types)
|
||||
* [Enums](#enums)
|
||||
* [Sum types](#sum-types)
|
||||
* [Type aliases](#type-aliases)
|
||||
* [Enums](#enums)
|
||||
* [Function Types](#function-types)
|
||||
* [Interfaces](#interfaces)
|
||||
* [Sum types](#sum-types)
|
||||
* [Option/Result types & error handling](#optionresult-types-and-error-handling)
|
||||
* [Handling optionals/results](#handling-optionalsresults)
|
||||
* [Custom error types](#custom-error-types)
|
||||
@ -2966,7 +2966,185 @@ particularly useful for initializing a C library.
|
||||
|
||||
## Type Declarations
|
||||
|
||||
### Type aliases
|
||||
|
||||
To define a new type `NewType` as an alias for `ExistingType`,
|
||||
do `type NewType = ExistingType`.<br/>
|
||||
This is a special case of a [sum type](#sum-types) declaration.
|
||||
|
||||
### Enums
|
||||
|
||||
```v
|
||||
enum Color as u8 {
|
||||
red
|
||||
green
|
||||
blue
|
||||
}
|
||||
|
||||
mut color := Color.red
|
||||
// V knows that `color` is a `Color`. No need to use `color = Color.green` here.
|
||||
color = .green
|
||||
println(color) // "green"
|
||||
match color {
|
||||
.red { println('the color was red') }
|
||||
.green { println('the color was green') }
|
||||
.blue { println('the color was blue') }
|
||||
}
|
||||
```
|
||||
|
||||
The enum type can be any integer type, but can be ommited, if it is `int`: `enum Color {`.
|
||||
|
||||
Enum match must be exhaustive or have an `else` branch.
|
||||
This ensures that if a new enum field is added, it's handled everywhere in the code.
|
||||
|
||||
Enum fields cannot re-use reserved keywords. However, reserved keywords may be escaped
|
||||
with an @.
|
||||
|
||||
```v
|
||||
enum Color {
|
||||
@none
|
||||
red
|
||||
green
|
||||
blue
|
||||
}
|
||||
|
||||
color := Color.@none
|
||||
println(color)
|
||||
```
|
||||
|
||||
Integers may be assigned to enum fields.
|
||||
|
||||
```v
|
||||
enum Grocery {
|
||||
apple
|
||||
orange = 5
|
||||
pear
|
||||
}
|
||||
|
||||
g1 := int(Grocery.apple)
|
||||
g2 := int(Grocery.orange)
|
||||
g3 := int(Grocery.pear)
|
||||
println('Grocery IDs: $g1, $g2, $g3')
|
||||
```
|
||||
|
||||
Output: `Grocery IDs: 0, 5, 6`.
|
||||
|
||||
Operations are not allowed on enum variables; they must be explicitly cast to `int`.
|
||||
|
||||
Enums can have methods, just like structs.
|
||||
|
||||
```v
|
||||
enum Cycle {
|
||||
one
|
||||
two
|
||||
three
|
||||
}
|
||||
|
||||
fn (c Cycle) next() Cycle {
|
||||
match c {
|
||||
.one {
|
||||
return .two
|
||||
}
|
||||
.two {
|
||||
return .three
|
||||
}
|
||||
.three {
|
||||
return .one
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mut c := Cycle.one
|
||||
for _ in 0 .. 10 {
|
||||
println(c)
|
||||
c = c.next()
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
```
|
||||
|
||||
### Function Types
|
||||
|
||||
You can use type aliases for naming specific function signatures - for
|
||||
example:
|
||||
|
||||
```v
|
||||
type Filter = fn (string) string
|
||||
```
|
||||
|
||||
This works like any other type - for example, a function can accept an
|
||||
argument of a function type:
|
||||
|
||||
```v
|
||||
type Filter = fn (string) string
|
||||
|
||||
fn filter(s string, f Filter) string {
|
||||
return f(s)
|
||||
}
|
||||
```
|
||||
|
||||
V has duck-typing, so functions don't need to declare compatibility with
|
||||
a function type - they just have to be compatible:
|
||||
|
||||
```v
|
||||
fn uppercase(s string) string {
|
||||
return s.to_upper()
|
||||
}
|
||||
|
||||
// now `uppercase` can be used everywhere where Filter is expected
|
||||
```
|
||||
|
||||
Compatible functions can also be explicitly cast to a function type:
|
||||
|
||||
```v oksyntax
|
||||
my_filter := Filter(uppercase)
|
||||
```
|
||||
|
||||
The cast here is purely informational - again, duck-typing means that the
|
||||
resulting type is the same without an explicit cast:
|
||||
|
||||
```v oksyntax
|
||||
my_filter := uppercase
|
||||
```
|
||||
|
||||
You can pass the assigned function as an argument:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', my_filter)) // prints `HELLO WORLD`
|
||||
```
|
||||
|
||||
And you could of course have passed it directly as well, without using a
|
||||
local variable:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', uppercase))
|
||||
```
|
||||
|
||||
And this works with anonymous functions as well:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', fn (s string) string {
|
||||
return s.to_upper()
|
||||
}))
|
||||
```
|
||||
|
||||
You can see the complete
|
||||
[example here](https://github.com/vlang/v/tree/master/examples/function_types.v).
|
||||
|
||||
### Interfaces
|
||||
|
||||
```v
|
||||
// interface-example.1
|
||||
struct Dog {
|
||||
@ -3198,177 +3376,6 @@ pub interface ReaderWriter {
|
||||
}
|
||||
```
|
||||
|
||||
### Function Types
|
||||
|
||||
You can use type aliases for naming specific function signatures - for
|
||||
example:
|
||||
|
||||
```v
|
||||
type Filter = fn (string) string
|
||||
```
|
||||
|
||||
This works like any other type - for example, a function can accept an
|
||||
argument of a function type:
|
||||
|
||||
```v
|
||||
type Filter = fn (string) string
|
||||
|
||||
fn filter(s string, f Filter) string {
|
||||
return f(s)
|
||||
}
|
||||
```
|
||||
|
||||
V has duck-typing, so functions don't need to declare compatibility with
|
||||
a function type - they just have to be compatible:
|
||||
|
||||
```v
|
||||
fn uppercase(s string) string {
|
||||
return s.to_upper()
|
||||
}
|
||||
|
||||
// now `uppercase` can be used everywhere where Filter is expected
|
||||
```
|
||||
|
||||
Compatible functions can also be explicitly cast to a function type:
|
||||
|
||||
```v oksyntax
|
||||
my_filter := Filter(uppercase)
|
||||
```
|
||||
|
||||
The cast here is purely informational - again, duck-typing means that the
|
||||
resulting type is the same without an explicit cast:
|
||||
|
||||
```v oksyntax
|
||||
my_filter := uppercase
|
||||
```
|
||||
|
||||
You can pass the assigned function as an argument:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', my_filter)) // prints `HELLO WORLD`
|
||||
```
|
||||
|
||||
And you could of course have passed it directly as well, without using a
|
||||
local variable:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', uppercase))
|
||||
```
|
||||
|
||||
And this works with anonymous functions as well:
|
||||
|
||||
```v oksyntax
|
||||
println(filter('Hello world', fn (s string) string {
|
||||
return s.to_upper()
|
||||
}))
|
||||
```
|
||||
|
||||
You can see the complete
|
||||
[example here](https://github.com/vlang/v/tree/master/examples/function_types.v).
|
||||
|
||||
### Enums
|
||||
|
||||
```v
|
||||
enum Color as u8 {
|
||||
red
|
||||
green
|
||||
blue
|
||||
}
|
||||
|
||||
mut color := Color.red
|
||||
// V knows that `color` is a `Color`. No need to use `color = Color.green` here.
|
||||
color = .green
|
||||
println(color) // "green"
|
||||
match color {
|
||||
.red { println('the color was red') }
|
||||
.green { println('the color was green') }
|
||||
.blue { println('the color was blue') }
|
||||
}
|
||||
```
|
||||
|
||||
The enum type can be any integer type, but can be ommited, if it is `int`: `enum Color {`.
|
||||
|
||||
Enum match must be exhaustive or have an `else` branch.
|
||||
This ensures that if a new enum field is added, it's handled everywhere in the code.
|
||||
|
||||
Enum fields cannot re-use reserved keywords. However, reserved keywords may be escaped
|
||||
with an @.
|
||||
|
||||
```v
|
||||
enum Color {
|
||||
@none
|
||||
red
|
||||
green
|
||||
blue
|
||||
}
|
||||
|
||||
color := Color.@none
|
||||
println(color)
|
||||
```
|
||||
|
||||
Integers may be assigned to enum fields.
|
||||
|
||||
```v
|
||||
enum Grocery {
|
||||
apple
|
||||
orange = 5
|
||||
pear
|
||||
}
|
||||
|
||||
g1 := int(Grocery.apple)
|
||||
g2 := int(Grocery.orange)
|
||||
g3 := int(Grocery.pear)
|
||||
println('Grocery IDs: $g1, $g2, $g3')
|
||||
```
|
||||
|
||||
Output: `Grocery IDs: 0, 5, 6`.
|
||||
|
||||
Operations are not allowed on enum variables; they must be explicitly cast to `int`.
|
||||
|
||||
Enums can have methods, just like structs.
|
||||
|
||||
```v
|
||||
enum Cycle {
|
||||
one
|
||||
two
|
||||
three
|
||||
}
|
||||
|
||||
fn (c Cycle) next() Cycle {
|
||||
match c {
|
||||
.one {
|
||||
return .two
|
||||
}
|
||||
.two {
|
||||
return .three
|
||||
}
|
||||
.three {
|
||||
return .one
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mut c := Cycle.one
|
||||
for _ in 0 .. 10 {
|
||||
println(c)
|
||||
c = c.next()
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
```
|
||||
|
||||
### Sum types
|
||||
|
||||
A sum type instance can hold a value of several different types. Use the `type`
|
||||
@ -3533,12 +3540,6 @@ fn pass_time(w World) {
|
||||
}
|
||||
```
|
||||
|
||||
### Type aliases
|
||||
|
||||
To define a new type `NewType` as an alias for `ExistingType`,
|
||||
do `type NewType = ExistingType`.<br/>
|
||||
This is a special case of a [sum type](#sum-types) declaration.
|
||||
|
||||
### Option/Result types and error handling
|
||||
|
||||
Optional types are for types which may represent `none`. Result types may
|
||||
|
Loading…
Reference in New Issue
Block a user