mirror of
https://github.com/vlang/v.git
synced 2025-09-11 16:36:20 -04: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>
|
<tr><td width=33% valign=top>
|
||||||
|
|
||||||
* [Type Declarations](#type-declarations)
|
* [Type Declarations](#type-declarations)
|
||||||
* [Interfaces](#interfaces)
|
|
||||||
* [Function Types](#function-types)
|
|
||||||
* [Enums](#enums)
|
|
||||||
* [Sum types](#sum-types)
|
|
||||||
* [Type aliases](#type-aliases)
|
* [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)
|
* [Option/Result types & error handling](#optionresult-types-and-error-handling)
|
||||||
* [Handling optionals/results](#handling-optionalsresults)
|
* [Handling optionals/results](#handling-optionalsresults)
|
||||||
* [Custom error types](#custom-error-types)
|
* [Custom error types](#custom-error-types)
|
||||||
@ -2966,7 +2966,185 @@ particularly useful for initializing a C library.
|
|||||||
|
|
||||||
## Type Declarations
|
## 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
|
### Interfaces
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// interface-example.1
|
// interface-example.1
|
||||||
struct Dog {
|
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
|
### Sum types
|
||||||
|
|
||||||
A sum type instance can hold a value of several different types. Use the `type`
|
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
|
### Option/Result types and error handling
|
||||||
|
|
||||||
Optional types are for types which may represent `none`. Result types may
|
Optional types are for types which may represent `none`. Result types may
|
||||||
|
Loading…
x
Reference in New Issue
Block a user