From 9a8602ff03f882761f1240bc340e91b6860a051f Mon Sep 17 00:00:00 2001 From: kahsa Date: Sat, 12 Nov 2022 18:42:30 +0900 Subject: [PATCH] doc: improve types order (#16399) --- doc/docs.md | 363 ++++++++++++++++++++++++++-------------------------- 1 file changed, 182 insertions(+), 181 deletions(-) diff --git a/doc/docs.md b/doc/docs.md index 741dee5ce2..4886cc9d24 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -113,11 +113,11 @@ To do so, run the command `v up`. * [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`.
+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`.
-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