doc: document `type Fn = fn (string) string` (type aliases) (#10471)

pull/10495/head
Rasmus Schultz 2021-06-22 11:39:57 +02:00 committed by GitHub
parent 72358833e0
commit 1c80741886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 5 deletions

View File

@ -67,7 +67,7 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
* [Returning multiple values](#returning-multiple-values)
* [Symbol visibility](#symbol-visibility)
* [Variables](#variables)
* [Types](#types)
* [V types](#v-types)
* [Strings](#strings)
* [Numbers](#numbers)
* [Arrays](#arrays)
@ -102,7 +102,7 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
* [Modules](#modules)
* [Manage Packages](#manage-packages)
* [Publish package](#publish-package)
* [Types 2](#types-2)
* [Type Declarations](#type-declarations)
* [Interfaces](#interfaces)
* [Enums](#enums)
* [Sum types](#sum-types)
@ -399,7 +399,7 @@ fn draw(ctx &gg.Context) {
}
```
## Types
## V Types
### Primitive types
@ -2403,7 +2403,7 @@ Modules are up to date.
**Optional:** tag your V module with `vlang` and `vlang-module` on github.com
to allow a better search experiance.
## Types 2
## Type Declarations
### Interfaces
@ -2499,6 +2499,74 @@ fn main() {
}
```
### 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
@ -4738,7 +4806,7 @@ union
unsafe
__offsetof
```
See also [Types](#types).
See also [V Types](#v-types).
## Appendix II: Operators

View File

@ -0,0 +1,32 @@
// Function signatures can be declared as types:
type Filter = fn (string) string
// Functions can accept function types as arguments:
fn filter(s string, f Filter) string {
return f(s)
}
// Declare a function with a matching signature:
fn uppercase(s string) string {
return s.to_upper()
}
fn main() {
// A function can be assigned to a matching type:
my_filter := Filter(uppercase)
// You don't strictly need the `Filter` cast - it's only used
// here to illustrate how these types are compatible.
// All of the following prints "HELLO WORLD":
println(filter('Hello world', my_filter))
println(filter('Hello world', uppercase))
println(filter('Hello world', fn (s string) string {
return s.to_upper()
}))
}