1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

docs: unify format of notes (#17294)

This commit is contained in:
Makhnev Petr
2023-02-13 12:29:02 +04:00
committed by GitHub
parent e7fcf66095
commit c8c70de87d
24 changed files with 422 additions and 252 deletions

View File

@ -209,7 +209,7 @@ by using any of the following commands in a terminal:
</table>
<!--
NB: there are several special keywords, which you can put after the code fences for v:
Note: There are several special keywords, which you can put after the code fences for v:
compile, cgen, live, ignore, failcompile, okfmt, oksyntax, badsyntax, wip, nofmt
For more details, do: `v check-md`
-->
@ -252,10 +252,11 @@ This means that a "hello world" program in V is as simple as
println('hello world')
```
Note: if you do not use explicitly `fn main() {}`, you need to make sure, that all your
declarations, come before any variable assignment statements, or top level function calls,
since V will consider everything after the first assignment/function call as part of your
implicit main function.
> **Note**
> If you do not use explicitly `fn main() {}`, you need to make sure, that all your
> declarations, come before any variable assignment statements, or top level function calls,
> since V will consider everything after the first assignment/function call as part of your
> implicit main function.
## Running a project folder with several files
@ -285,13 +286,15 @@ import os
println(os.args)
```
NB: after a successful run, V will delete the generated executable.
If you want to keep it, use `v -keepc run .` instead, or just compile
manually with `v .` .
> **Note**
> After a successful run, V will delete the generated executable.
> If you want to keep it, use `v -keepc run .` instead, or just compile
> manually with `v .` .
NB: any V compiler flags should be passed *before* the `run` command.
Everything after the source file/folder, will be passed to the program
as is - it will not be processed by V.
> **Note**
> Any V compiler flags should be passed *before* the `run` command.
> Everything after the source file/folder, will be passed to the program
> as is - it will not be processed by V.
## Comments
@ -359,8 +362,9 @@ Functions are private (not exported) by default.
To allow other [modules](#module-imports) to use them, prepend `pub`. The same applies
to [structs](#structs), [constants](#constants) and [types](#type-declarations).
Note: `pub` can only be used from a named module.
For information about creating a module, see [Modules](#modules).
> **Note**
> `pub` can only be used from a named module.
> For information about creating a module, see [Modules](#modules).
## Variables
@ -477,7 +481,8 @@ voidptr // this one is mostly used for [C interoperability](#v-and-c)
any // similar to C's void* and Go's interface{}
```
Please note that unlike C and Go, `int` is always a 32 bit integer.
> **Note**
> Unlike C and Go, `int` is always a 32 bit integer.
There is an exception to the rule that all operators
in V must have values of the same type on both sides. A small primitive type
@ -623,9 +628,10 @@ To use a format specifier, follow this pattern:
`${varname:[flags][width][.precision][type]}`
- flags: may be zero or more of the following: `-` to left-align output within the field, `0` to use
`0` as the padding character instead of the default `space` character. (Note: V does not currently
support the use of `'` or `#` as format flags, and V supports but doesn't need `+` to right-align
since that's the default.)
`0` as the padding character instead of the default `space` character.
> **Note**
> V does not currently support the use of `'` or `#` as format flags, and V supports but
> doesn't need `+` to right-align since that's the default.
- width: may be an integer value describing the minimum width of total field to output.
- precision: an integer value preceded by a `.` will guarantee that many digits after the decimal
point, if the input variable is a float. Ignored if variable is an integer.
@ -637,13 +643,15 @@ To use a format specifier, follow this pattern:
integer and will render it as octal digits, `b` requires an integer and will render it as binary
digits, `s` requires a string (almost never used).
Note: when a numeric type can render alphabetic characters, such as hex strings or special values
like `infinity`, the lowercase version of the type forces lowercase alphabetics and the uppercase
version forces uppercase alphabetics.
> **Note**
> When a numeric type can render alphabetic characters, such as hex strings or special values
> like `infinity`, the lowercase version of the type forces lowercase alphabetics and the
> uppercase version forces uppercase alphabetics.
Also note: in most cases, it's best to leave the format type empty. Floats will be rendered by
default as `g`, integers will be rendered by default as `d`, and `s` is almost always redundant.
There are only three cases where specifying a type is recommended:
> **Note**
> In most cases, it's best to leave the format type empty. Floats will be rendered by
> default as `g`, integers will be rendered by default as `d`, and `s` is almost always redundant.
> There are only three cases where specifying a type is recommended:
- format strings are parsed at compile time, so specifying a type can help detect errors then
- format strings default to using lowercase letters for hex digits and the `e` in exponents. Use a
@ -887,7 +895,8 @@ println(nums.len) // "0"
`data` is a field (of type `voidptr`) with the address of the first
element. This is for low-level [`unsafe`](#memory-unsafe-code) code.
Note that the fields are read-only and can't be modified by the user.
> **Note**
> Fields are read-only and can't be modified by the user.
#### Array Initialization
@ -933,7 +942,8 @@ for i in 0 .. 1000 {
}
```
Note: The above code uses a [range `for`](#range-for) statement.
> **Note**
> The above code uses a [range `for`](#range-for) statement.
You can initialize the array by accessing the `it` variable which gives
the index as shown here:
@ -1231,7 +1241,7 @@ You can call .clone() on the slice, if you do want to have an independent copy r
```v
mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4].clone()
b[0] = 7 // NB: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
b[0] = 7 // Note: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
println(a) // [0, 1, 2, 3, 4, 5]
println(b) // [7, 3]
```
@ -1441,8 +1451,9 @@ fn main() {
}
```
Note: This will import the module as well. Also, this is not allowed for
constants - they must always be prefixed.
> **Note**
> This will import the module as well. Also, this is not allowed for
> constants - they must always be prefixed.
You can import several specific symbols at once:
@ -1459,7 +1470,8 @@ println('Your OS is ${current_os}.')
Any imported module name can be aliased using the `as` keyword:
NOTE: this example will not compile unless you have created `mymod/sha256.v`
> **Note**
> This example will not compile unless you have created `mymod/sha256.v`
```v failcompile
import crypto.sha256
@ -1737,7 +1749,8 @@ println(num)
Constants can also be used in the range branch expressions.
Note: `match` as an expression is not usable in `for` loop and `if` statements.
> **Note**
> `match` as an expression is not usable in `for` loop and `if` statements.
### In operator
@ -2273,12 +2286,12 @@ new_button(ButtonConfig{text:'Click me', width:100})
This only works for functions that take a struct for the last argument.
NB: the `[params]` tag is used to tell V, that the trailing struct parameter
can be omitted *entirely*, so that you can write `button := new_button()`.
Without it, you have to specify *at least* one of the field names, even if it
has its default value, otherwise the compiler will produce this error message,
when you call the function with no parameters:
`error: expected 1 arguments, but got 0`.
> Note the `[params]` tag is used to tell V, that the trailing struct parameter
> can be omitted *entirely*, so that you can write `button := new_button()`.
> Without it, you have to specify *at least* one of the field names, even if it
> has its default value, otherwise the compiler will produce this error message,
> when you call the function with no parameters:
> `error: expected 1 arguments, but got 0`.
### Access modifiers
@ -2526,7 +2539,8 @@ Output: `Size: 4B, clr1.b: 136, clr2.b: 0`
Union member access must be performed in an `unsafe` block.
Note that the embedded struct arguments are not necessarily stored in the order listed.
> **Note**
> Embedded struct arguments are not necessarily stored in the order listed.
## Functions 2
@ -2541,7 +2555,8 @@ are a function of their arguments only, and their evaluation has no side effects
Function arguments are immutable by default, even when [references](#references) are passed.
Note that V is not a purely functional language however.
> **Note**
> V is not a purely functional language however.
There is a compiler flag to enable global variables (`-enable-globals`), but this is
intended for low-level applications like kernels and drivers.
@ -2901,8 +2916,9 @@ fn panic(s string) // prints a message and backtraces on stderr, and terminates
fn print_backtrace() // prints backtraces on stderr
```
Note: Although the `print` functions take a string, V accepts other printable types too.
See below for details.
> **Note**
> Although the `print` functions take a string, V accepts other printable types too.
> See below for details.
There is also a special built-in function called [`dump`](#dumping-expressions-at-runtime).
@ -3398,7 +3414,8 @@ They are just a convenient way to write `i.some_function()` instead of
`some_function(i)`, similar to how struct methods can be looked at, as
a convenience for writing `s.xyz()` instead of `xyz(s)`.
N.B. This feature is NOT a "default implementation" like in C#.
> **Note**
> This feature is NOT a "default implementation" like in C#.
For example, if a struct `cat` is wrapped in an interface `a`, that has
implemented a method with the same name `speak`, as a method implemented by
@ -3744,7 +3761,9 @@ user := repo.find_user_by_id(7) or { return }
Here, you can either call `panic()` or `exit()`, which will stop the execution of the
entire program, or use a control flow statement (`return`, `break`, `continue`, etc)
to break from the current block.
Note that `break` and `continue` can only be used inside a `for` loop.
> **Note**
> `break` and `continue` can only be used inside a `for` loop.
V does not have a way to forcibly "unwrap" an option (as other languages do,
for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err) }` instead.
@ -4303,7 +4322,8 @@ assert fails it is reported to *stderr*, and the values on each side of a compar
unexpected value. Assert statements can be used in any function, not just test ones,
which is handy when developing new functionality, to keep your invariants in check.
Note: all `assert` statements are *removed*, when you compile your program with the `-prod` flag.
> **Note**
> All `assert` statements are *removed*, when you compile your program with the `-prod` flag.
### Asserts with an extra message
@ -4351,8 +4371,9 @@ assert_continues_example.v:3: FAIL: fn main.abc: assert ii == 2
right value: 2
```
Note: V also supports a command line flag `-assert continues`, which will change the
behaviour of all asserts globally, as if you had tagged every function with `[assert_continues]`.
> **Note**
> V also supports a command line flag `-assert continues`, which will change the
> behaviour of all asserts globally, as if you had tagged every function with `[assert_continues]`.
### Test files
@ -4381,10 +4402,11 @@ fn test_hello() {
To run the test file above, use `v hello_test.v`. This will check that the function `hello` is
producing the correct output. V executes all test functions in the file.
Note: all `_test.v` files (both external and internal ones), are compiled as *separate programs*.
In other words, you may have as many `_test.v` files, and tests in them as you like, they will
not affect the compilation of your other code in `.v` files normally at all, but only when you
do explicitly `v file_test.v` or `v test .`.
> **Note**
> All `_test.v` files (both external and internal ones), are compiled as *separate programs*.
> In other words, you may have as many `_test.v` files, and tests in them as you like, they will
> not affect the compilation of your other code in `.v` files normally at all, but only when you
> do explicitly `v file_test.v` or `v test .`.
* All test functions have to be inside a test file whose name ends in `_test.v`.
* Test function names must begin with `test_` to mark them for execution.
@ -4435,8 +4457,9 @@ put .v files with invalid V source code, or other tests, including known
failing ones, that should be run in a specific way/options by a parent _test.v
file.
NB: the path to the V compiler, is available through @VEXE, so a _test.v
file, can easily run *other* test files like this:
> **Note**
> The path to the V compiler, is available through @VEXE, so a _test.v
> file, can easily run *other* test files like this:
```v oksyntax
import os
@ -4484,9 +4507,10 @@ For developers willing to have more low level control, autofree can be disabled
`-manualfree`, or by adding a `[manualfree]` on each function that wants manage its
memory manually. (See [attributes](#attributes)).
Note 2: Autofree is still WIP. Until it stabilises and becomes the default, please
avoid using it. Right now allocations are handled by a minimal and well performing GC
until V's autofree engine is production ready.
> **Note**
> Autofree is still WIP. Until it stabilises and becomes the default, please
> avoid using it. Right now allocations are handled by a minimal and well performing GC
> until V's autofree engine is production ready.
**Examples**
@ -5616,10 +5640,11 @@ With the example above:
That corresponds to `$if customflag ? {}`, but for a whole file, not just a
single block. `customflag` should be a snake_case identifier, it can not
contain arbitrary characters (only lower case latin letters + numbers + `_`).
NB: a combinatorial `_d_customflag_linux.c.v` postfix will not work.
If you do need a custom flag file, that has platform dependent code, use the
postfix `_d_customflag.v`, and then use plaftorm dependent compile time
conditional blocks inside it, i.e. `$if linux {}` etc.
> **Note**
> A combinatorial `_d_customflag_linux.c.v` postfix will not work.
> If you do need a custom flag file, that has platform dependent code, use the
> postfix `_d_customflag.v`, and then use plaftorm dependent compile time
> conditional blocks inside it, i.e. `$if linux {}` etc.
- `_notd_customflag.v` => similar to _d_customflag.v, but will be used
*only* if you do NOT pass `-d customflag` to V.
@ -5669,7 +5694,8 @@ If you suspect your program does violate memory-safety, you have a head start on
finding the cause: look at the `unsafe` blocks (and how they interact with
surrounding code).
* Note: This is work in progress.
> **Note**
> This is work in progress.
## Structs with reference fields
@ -5797,10 +5823,11 @@ with `-prod`. There are some situations though, where you may want to give
additional hints to the compiler, so that it can further optimize some
blocks of code.
NB: These are *rarely* needed, and should not be used, unless you
*profile your code*, and then see that there are significant benefits for them.
To cite gcc's documentation: "programmers are notoriously bad at predicting
how their programs actually perform".
> **Note**
> These are *rarely* needed, and should not be used, unless you
> *profile your code*, and then see that there are significant benefits for them.
> To cite gcc's documentation: "programmers are notoriously bad at predicting
> how their programs actually perform".
`[inline]` - you can tag functions with `[inline]`, so the C compiler will
try to inline them, which in some cases, may be beneficial for performance,
@ -5970,8 +5997,9 @@ or
v -os linux .
```
NB: Cross-compiling a windows binary on a linux machine requires the GNU C compiler for
MinGW-w64 (targeting Win64) to first be installed.
> **Note**
> Cross-compiling a windows binary on a linux machine requires the GNU C compiler for
> MinGW-w64 (targeting Win64) to first be installed.
For Ubuntu/Debian based distributions:
@ -6113,7 +6141,7 @@ fn main() {
// C.sqlite3_open(db_path.str, &db)
query := 'select count(*) from users'
stmt := &C.sqlite3_stmt(0)
// NB: you can also use the `.str` field of a V string,
// Note: You can also use the `.str` field of a V string,
// to get its C style zero terminated representation
C.sqlite3_prepare_v2(db, &char(query.str), -1, &stmt, 0)
C.sqlite3_step(stmt)
@ -6152,7 +6180,8 @@ Add `#flag` directives to the top of your V files to provide C compilation flags
You can (optionally) use different flags for different targets.
Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported.
NB: Each flag must go on its own line (for now)
> **Note**
> Each flag must go on its own line (for now)
```v oksyntax
#flag linux -lsdl2
@ -6228,11 +6257,13 @@ Module {
#include "header.h"
```
NB: @VMODROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*.
Any .v file beside or below the folder where the v.mod file is,
can use `#flag @VMODROOT/abc` to refer to this folder.
The @VMODROOT folder is also *prepended* to the module lookup path,
so you can *import* other modules under your @VMODROOT, by just naming them.
> **Note**
> @VMODROOT will be replaced by V with the *nearest parent folder,
> where there is a v.mod file*.
> Any .v file beside or below the folder where the v.mod file is,
> can use `#flag @VMODROOT/abc` to refer to this folder.
> The @VMODROOT folder is also *prepended* to the module lookup path,
> so you can *import* other modules under your @VMODROOT, by just naming them.
The instructions above will make V look for an compiled .o file in
your module `folder/c/implementation.o`.
@ -6252,10 +6283,11 @@ Ordinary zero terminated C strings can be converted to V strings with
`unsafe { &char(cstring).vstring() }` or if you know their length already with
`unsafe { &char(cstring).vstring_with_len(len) }`.
NB: The .vstring() and .vstring_with_len() methods do NOT create a copy of the `cstring`,
so you should NOT free it after calling the method `.vstring()`.
If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that,
since they return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
> **Note**
> The `.vstring()` and `.vstring_with_len()` methods do NOT create a copy of the `cstring`,
> so you should NOT free it after calling the method `.vstring()`.
> If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that,
> since they return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
On Windows, C APIs often return so called `wide` strings (utf16 encoding).
These can be converted to V strings with `string_from_wide(&u16(cwidestring))` .
@ -6475,7 +6507,7 @@ An example `deploy.vsh`:
```v oksyntax
#!/usr/bin/env -S v
// Note: the shebang line above, associates the .vsh file to V on Unix-like systems,
// Note: The shebang line above, associates the .vsh file to V on Unix-like systems,
// so it can be run just by specifying the path to the .vsh file, once it's made
// executable, using `chmod +x deploy.vsh`, i.e. after that chmod command, you can
// run the .vsh script, by just typing its name/path like this: `./deploy.vsh`