doc: use nested list for Table of Contents
A nested list is much easier to browse than a table. Move Imports section below Arrays and Maps for Types grouping. Move Defer section to Statements group. Move vfmt section next to Profiling for Tools group.pull/5519/head
parent
09236a438b
commit
6b1b5e001d
279
doc/docs.md
279
doc/docs.md
|
@ -17,74 +17,79 @@ you can do in V.
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr><td>
|
||||||
<td width=16%><a href='#hello-world'>1. Hello world</a></td>
|
|
||||||
<td width=16%><a href='#comments'>2. Comments</a></td>
|
[Hello world](#hello-world)
|
||||||
<td width=16%><a href='#functions'>3. Functions</a></td>
|
[Comments](#comments)
|
||||||
<td width=16%><a href='#variables'>4. Variables</a></td>
|
[Functions](#functions)
|
||||||
<td width=16%><a href='#primitive-types'>5. Primitive types</a></td>
|
[Variables](#variables)
|
||||||
<td width=16%><a href='#strings'>6. Strings</a></td>
|
[Types](#types)
|
||||||
</tr>
|
* [Primitive types](#primitive-types)
|
||||||
<tr>
|
* [Strings](#strings)
|
||||||
<td><a href='#imports'>7. Imports</a></td>
|
* [Arrays](#arrays)
|
||||||
<td><a href='#arrays'>Arrays</a></td>
|
* [Maps](#maps)
|
||||||
<td><a href='#maps'>Maps</a></td>
|
|
||||||
<td><a href='#if'>If</a></td>
|
[Imports](#imports)
|
||||||
<td><a href='#in-operator'>In Operator</a></td>
|
[Statements & Expressions](#statements--expressions)
|
||||||
<td><a href='#for-loop'>For loop</a></td>
|
* [If](#if)
|
||||||
</tr>
|
* [In Operator](#in-operator)
|
||||||
<tr>
|
* [For loop](#for-loop)
|
||||||
<td><a href='#match'>Match</a></td>
|
* [Match](#match)
|
||||||
<td><a href='#structs'>Structs</a></td>
|
* [Defer](#defer)
|
||||||
<td><a href='#short-struct-initialization-syntax'>Short struct init syntax</a></td>
|
|
||||||
<td><a href='#access-modifiers'>Access modifiers</a></td>
|
[Structs](#structs)
|
||||||
<td><a href='#methods'>Methods</a></td>
|
* [Short struct init syntax](#short-struct-initialization-syntax)
|
||||||
<td><a href='#pure-functions-by-default'>Pure functions by default</a></td>
|
* [Access modifiers](#access-modifiers)
|
||||||
</tr>
|
* [Methods](#methods)
|
||||||
<tr>
|
|
||||||
<td><a href='#anonymous--high-order-functions'>Anonymous & high order fns</a></td>
|
[println](#println)
|
||||||
<td><a href='#references'>References</a></td>
|
|
||||||
<td><a href='#constants'>Constants</a></td>
|
</td><td>
|
||||||
<td><a href='#println'>println</a></td>
|
|
||||||
<td><a href='#modules'>Modules</a></td>
|
[Functions 2](#functions-2)
|
||||||
<td><a href='#interfaces'>Interfaces</a></td>
|
* [Pure functions by default](#pure-functions-by-default)
|
||||||
</tr>
|
* [Anonymous & high order functions](#anonymous--high-order-functions)
|
||||||
<tr>
|
|
||||||
<td><a href='#enums'>Enums</a></td>
|
[References](#references)
|
||||||
<td><a href='#sum-types'>Sum types</a></td>
|
[Modules](#modules)
|
||||||
<td><a href='#optionresult-types-and-error-handling'>Option/Result & error handling</a></td>
|
[Constants](#constants)
|
||||||
<td><a href='#generics'>Generics</a></td>
|
[Types 2](#types-2)
|
||||||
<td><a href='#concurrency'>Concurrency</a></td>
|
* [Interfaces](#interfaces)
|
||||||
<td><a href='#decoding-json'>Decoding JSON</a></td>
|
* [Enums](#enums)
|
||||||
</tr>
|
* [Sum types](#sum-types)
|
||||||
<tr>
|
* [Option/Result types & error handling](#optionresult-types-and-error-handling)
|
||||||
<td><a href='#testing'>Testing</a></td>
|
|
||||||
<td><a href='#memory-management'>Memory managment</a></td>
|
[Generics](#generics)
|
||||||
<td><a href='#defer'>Defer</a></td>
|
[Concurrency](#concurrency)
|
||||||
<td><a href='#orm'>ORM</a></td>
|
[Decoding JSON](#decoding-json)
|
||||||
<td><a href='#vfmt'>vfmt</a></td>
|
[Testing](#testing)
|
||||||
<td><a href='#writing-documentation'>Writing documentation</a></td>
|
[Memory management](#memory-management)
|
||||||
</tr>
|
[ORM](#orm)
|
||||||
<tr>
|
[Writing documentation](#writing-documentation)
|
||||||
<td><a href='#profiling'>Profiling</a></td>
|
[Tools](#tools)
|
||||||
<td><a href='#calling-c-functions-from-v'>Calling C functions from V</a></td>
|
* [vfmt](#vfmt)
|
||||||
<td><a href='#conditional-compilation'>Conditional compilation</a></td>
|
* [Profiling](#profiling)
|
||||||
<td><a href='#compile-time-pseudo-variables'>Compile time pseudo variables</a></td>
|
|
||||||
<td><a href='#reflection-via-codegen'>Reflection via codegen</a></td>
|
</td><td>
|
||||||
<td><a href='#limited-operator-overloading'>Limited operator overloading</a></td>
|
|
||||||
</tr>
|
[Advanced](#advanced)
|
||||||
<tr>
|
* [Calling C functions from V](#calling-c-functions-from-v)
|
||||||
<td><a href='#inline-assembly'>Inline assembly</a></td>
|
* [Conditional compilation](#conditional-compilation)
|
||||||
<td><a href='#translating-cc-to-v'>Translating C/C++ to V</a></td>
|
* [Compile time pseudo variables](#compile-time-pseudo-variables)
|
||||||
<td><a href='#hot-code-reloading'>Hot code reloading</a></td>
|
* [Reflection via codegen](#reflection-via-codegen)
|
||||||
<td><a href='#cross-compilation'>Cross compilation</a></td>
|
* [Limited operator overloading](#limited-operator-overloading)
|
||||||
<td><a href='#cross-platform-shell-scripts-in-v'>Cross-platform shell scripts in V</a></td>
|
* [Inline assembly](#inline-assembly)
|
||||||
<td><a href='#attributes'>Attributes</a></td>
|
* [Translating C/C++ to V](#translating-cc-to-v)
|
||||||
</tr>
|
* [Hot code reloading](#hot-code-reloading)
|
||||||
<tr>
|
* [Cross compilation](#cross-compilation)
|
||||||
<td><a href='#appendix-i-keywords'>Appendix I: Keywords</a></td>
|
* [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v)
|
||||||
<td><a href='#appendix-ii-operators'>Appendix II: Operators</a></td>
|
* [Attributes](#attributes)
|
||||||
</tr>
|
|
||||||
|
[Appendices](#appendices)
|
||||||
|
* [Keywords](#appendix-i-keywords)
|
||||||
|
* [Operators](#appendix-ii-operators)
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,7 +275,9 @@ fn main() {
|
||||||
|
|
||||||
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will cause a compilation error.
|
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will cause a compilation error.
|
||||||
|
|
||||||
## Primitive types
|
## Types
|
||||||
|
|
||||||
|
### Primitive types
|
||||||
|
|
||||||
```v
|
```v
|
||||||
bool
|
bool
|
||||||
|
@ -313,7 +320,7 @@ or `i64` but not to `f32` or `u32`. (`f32` would mean precission
|
||||||
loss for large values and `u32` would mean loss of the sign for
|
loss for large values and `u32` would mean loss of the sign for
|
||||||
negative values).
|
negative values).
|
||||||
|
|
||||||
## Strings
|
### Strings
|
||||||
|
|
||||||
```v
|
```v
|
||||||
name := 'Bob'
|
name := 'Bob'
|
||||||
|
@ -379,20 +386,7 @@ s := r'hello\nworld'
|
||||||
println(s) // "hello\nworld"
|
println(s) // "hello\nworld"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Imports
|
### Arrays
|
||||||
|
|
||||||
```v
|
|
||||||
import os
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
name := os.input('Enter your name:')
|
|
||||||
println('Hello, $name!')
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Modules can be imported using keyword `import`. When using types, functions, and constants from other modules, the full path must be specified. In the example above, `name := input()` wouldn't work. That means that it's always clear from which module a function is called.
|
|
||||||
|
|
||||||
## Arrays
|
|
||||||
|
|
||||||
```v
|
```v
|
||||||
mut nums := [1, 2, 3]
|
mut nums := [1, 2, 3]
|
||||||
|
@ -455,7 +449,7 @@ println(upper) // ['HELLO', 'WORLD']
|
||||||
|
|
||||||
`it` is a builtin variable which refers to element currently being processed in filter/map methods.
|
`it` is a builtin variable which refers to element currently being processed in filter/map methods.
|
||||||
|
|
||||||
## Maps
|
### Maps
|
||||||
|
|
||||||
```v
|
```v
|
||||||
mut m := map[string]int // Only maps with string keys are allowed for now
|
mut m := map[string]int // Only maps with string keys are allowed for now
|
||||||
|
@ -473,7 +467,22 @@ numbers := {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## If
|
## Imports
|
||||||
|
|
||||||
|
```v
|
||||||
|
import os
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
name := os.input('Enter your name:')
|
||||||
|
println('Hello, $name!')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Modules can be imported using keyword `import`. When using types, functions, and constants from other modules, the full path must be specified. In the example above, `name := input()` wouldn't work. That means that it's always clear from which module a function is called.
|
||||||
|
|
||||||
|
## Statements & Expressions
|
||||||
|
|
||||||
|
### If
|
||||||
|
|
||||||
```v
|
```v
|
||||||
a := 10
|
a := 10
|
||||||
|
@ -503,7 +512,7 @@ else {
|
||||||
println(s) // "odd"
|
println(s) // "odd"
|
||||||
```
|
```
|
||||||
|
|
||||||
## In operator
|
### In operator
|
||||||
|
|
||||||
`in` allows to check whether an array or a map contains an element.
|
`in` allows to check whether an array or a map contains an element.
|
||||||
|
|
||||||
|
@ -530,7 +539,7 @@ if parser.token in [.plus, .minus, .div, .mult] {
|
||||||
|
|
||||||
V optimizes such expressions, so both `if` statements above produce the same machine code and no arrays are created.
|
V optimizes such expressions, so both `if` statements above produce the same machine code and no arrays are created.
|
||||||
|
|
||||||
## For loop
|
### For loop
|
||||||
|
|
||||||
V has only one looping construct: `for`.
|
V has only one looping construct: `for`.
|
||||||
|
|
||||||
|
@ -603,7 +612,7 @@ stuck in an infinite loop.
|
||||||
|
|
||||||
Here `i` doesn't need to be declared with `mut` since it's always going to be mutable by definition.
|
Here `i` doesn't need to be declared with `mut` since it's always going to be mutable by definition.
|
||||||
|
|
||||||
## Match
|
### Match
|
||||||
|
|
||||||
```v
|
```v
|
||||||
os := 'windows'
|
os := 'windows'
|
||||||
|
@ -645,6 +654,24 @@ fn is_red_or_blue(c Color) bool {
|
||||||
A match statement can also be used to branch on the variants of an `enum`
|
A match statement can also be used to branch on the variants of an `enum`
|
||||||
by using the shorthand `.variant_here` syntax.
|
by using the shorthand `.variant_here` syntax.
|
||||||
|
|
||||||
|
### Defer
|
||||||
|
|
||||||
|
A defer statement defers the execution of a block of statements until the surrounding function returns.
|
||||||
|
|
||||||
|
```v
|
||||||
|
fn read_log() {
|
||||||
|
f := os.open('log.txt')
|
||||||
|
defer { f.close() }
|
||||||
|
...
|
||||||
|
if !ok {
|
||||||
|
// defer statement will be called here, the file will be closed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
...
|
||||||
|
// defer statement will be called here, the file will be closed
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Structs
|
## Structs
|
||||||
|
|
||||||
```v
|
```v
|
||||||
|
@ -710,7 +737,7 @@ All struct fields are zeroed by default during the creation of the struct. Array
|
||||||
It's also possible to define custom default values.
|
It's also possible to define custom default values.
|
||||||
|
|
||||||
|
|
||||||
## Short struct initialization syntax
|
### Short struct initialization syntax
|
||||||
|
|
||||||
There are no default function argument values or named arguments, for that the short struct initialization syntax can be used instead:
|
There are no default function argument values or named arguments, for that the short struct initialization syntax can be used instead:
|
||||||
|
|
||||||
|
@ -747,7 +774,7 @@ new_button(ButtonConfig{text:'Click me', width:100})
|
||||||
|
|
||||||
This only works with functions that have a single struct argument.
|
This only works with functions that have a single struct argument.
|
||||||
|
|
||||||
## Access modifiers
|
### Access modifiers
|
||||||
|
|
||||||
Struct fields are private and immutable by default (making structs immutable as well).
|
Struct fields are private and immutable by default (making structs immutable as well).
|
||||||
Their access modifiers can be changed with
|
Their access modifiers can be changed with
|
||||||
|
@ -792,7 +819,7 @@ fn main() {
|
||||||
|
|
||||||
This means that defining public readonly fields is very easy in V, no need in getters/setters or properties.
|
This means that defining public readonly fields is very easy in V, no need in getters/setters or properties.
|
||||||
|
|
||||||
## Methods
|
### Methods
|
||||||
|
|
||||||
```v
|
```v
|
||||||
struct User {
|
struct User {
|
||||||
|
@ -820,7 +847,9 @@ In this example, the `can_register` method has a receiver of type `User` named `
|
||||||
The convention is not to use receiver names like `self` or `this`,
|
The convention is not to use receiver names like `self` or `this`,
|
||||||
but a short, preferably one letter long, name.
|
but a short, preferably one letter long, name.
|
||||||
|
|
||||||
## Pure functions by default
|
## Functions 2
|
||||||
|
|
||||||
|
### Pure functions by default
|
||||||
|
|
||||||
V functions are pure by default, meaning that their return values are a function of their arguments only,
|
V functions are pure by default, meaning that their return values are a function of their arguments only,
|
||||||
and their evaluation has no side effects.
|
and their evaluation has no side effects.
|
||||||
|
@ -885,7 +914,7 @@ fn register(u User) User {
|
||||||
user = register(user)
|
user = register(user)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Anonymous & high order functions
|
### Anonymous & high order functions
|
||||||
|
|
||||||
```v
|
```v
|
||||||
fn sqr(n int) int {
|
fn sqr(n int) int {
|
||||||
|
@ -1088,7 +1117,9 @@ fn init() int {
|
||||||
|
|
||||||
The init function cannot be public. It will be called automatically.
|
The init function cannot be public. It will be called automatically.
|
||||||
|
|
||||||
## Interfaces
|
## Types 2
|
||||||
|
|
||||||
|
### Interfaces
|
||||||
|
|
||||||
```v
|
```v
|
||||||
struct Dog {}
|
struct Dog {}
|
||||||
|
@ -1124,7 +1155,7 @@ println(perform(cat)) // "meow"
|
||||||
A type implements an interface by implementing its methods.
|
A type implements an interface by implementing its methods.
|
||||||
There is no explicit declaration of intent, no "implements" keyword.
|
There is no explicit declaration of intent, no "implements" keyword.
|
||||||
|
|
||||||
## Enums
|
### Enums
|
||||||
|
|
||||||
```v
|
```v
|
||||||
enum Color {
|
enum Color {
|
||||||
|
@ -1137,7 +1168,7 @@ color = .green
|
||||||
println(color) // "1" TODO: print "green"?
|
println(color) // "1" TODO: print "green"?
|
||||||
```
|
```
|
||||||
|
|
||||||
## Sum types
|
### Sum types
|
||||||
|
|
||||||
```v
|
```v
|
||||||
type Expr = BinaryExpr | UnaryExpr | IfExpr
|
type Expr = BinaryExpr | UnaryExpr | IfExpr
|
||||||
|
@ -1213,7 +1244,7 @@ There are 3 ways to access the cast variant inside a match branch:
|
||||||
|
|
||||||
Note: shadowing only works when the match expression is a variable. It will not work on struct fields, arrays indexing, or map key lookup.
|
Note: shadowing only works when the match expression is a variable. It will not work on struct fields, arrays indexing, or map key lookup.
|
||||||
|
|
||||||
## Option/Result types and error handling
|
### Option/Result types and error handling
|
||||||
|
|
||||||
```v
|
```v
|
||||||
struct User {
|
struct User {
|
||||||
|
@ -1430,24 +1461,6 @@ fn test() []int {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Defer
|
|
||||||
|
|
||||||
A defer statement defers the execution of a block of statements until the surrounding function returns.
|
|
||||||
|
|
||||||
```v
|
|
||||||
fn read_log() {
|
|
||||||
f := os.open('log.txt')
|
|
||||||
defer { f.close() }
|
|
||||||
...
|
|
||||||
if !ok {
|
|
||||||
// defer statement will be called here, the file will be closed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
...
|
|
||||||
// defer statement will be called here, the file will be closed
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## ORM
|
## ORM
|
||||||
|
|
||||||
(this is still in an alpha state)
|
(this is still in an alpha state)
|
||||||
|
@ -1495,20 +1508,6 @@ sql db { insert new_customer into Customer }
|
||||||
|
|
||||||
For more examples, see <a href='https://github.com/vlang/v/blob/master/vlib/orm/orm_test.v'>vlib/orm/orm_test.v</a>.
|
For more examples, see <a href='https://github.com/vlang/v/blob/master/vlib/orm/orm_test.v'>vlib/orm/orm_test.v</a>.
|
||||||
|
|
||||||
## vfmt
|
|
||||||
|
|
||||||
You don't need to worry about formatting your code or setting style guidelines.
|
|
||||||
`vfmt` takes care of that:
|
|
||||||
|
|
||||||
```v
|
|
||||||
v fmt file.v
|
|
||||||
```
|
|
||||||
|
|
||||||
It's recommended to set up your editor, so that vfmt runs on every save.
|
|
||||||
A vfmt run is usually pretty cheap (takes <30ms).
|
|
||||||
|
|
||||||
Always run `v fmt -w file.v` before pushing your code.
|
|
||||||
|
|
||||||
## Writing Documentation
|
## Writing Documentation
|
||||||
|
|
||||||
The way it works is very similar to Go. It's very simple: there's no need to
|
The way it works is very similar to Go. It's very simple: there's no need to
|
||||||
|
@ -1529,7 +1528,23 @@ An overview of the module must be placed in the first comment right after the mo
|
||||||
|
|
||||||
To generate documentation use vdoc, for example `v doc net.http`.
|
To generate documentation use vdoc, for example `v doc net.http`.
|
||||||
|
|
||||||
## Profiling
|
## Tools
|
||||||
|
|
||||||
|
### vfmt
|
||||||
|
|
||||||
|
You don't need to worry about formatting your code or setting style guidelines.
|
||||||
|
`vfmt` takes care of that:
|
||||||
|
|
||||||
|
```v
|
||||||
|
v fmt file.v
|
||||||
|
```
|
||||||
|
|
||||||
|
It's recommended to set up your editor, so that vfmt runs on every save.
|
||||||
|
A vfmt run is usually pretty cheap (takes <30ms).
|
||||||
|
|
||||||
|
Always run `v fmt -w file.v` before pushing your code.
|
||||||
|
|
||||||
|
### Profiling
|
||||||
|
|
||||||
V has good support for profiling your programs: `v -profile profile.txt run file.v`
|
V has good support for profiling your programs: `v -profile profile.txt run file.v`
|
||||||
That will produce a profile.txt file, which you can then analyze.
|
That will produce a profile.txt file, which you can then analyze.
|
||||||
|
@ -2016,6 +2031,8 @@ fn C.WinFunction()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Appendices
|
||||||
|
|
||||||
## Appendix I: Keywords
|
## Appendix I: Keywords
|
||||||
|
|
||||||
V has 23 keywords:
|
V has 23 keywords:
|
||||||
|
|
Loading…
Reference in New Issue