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`

View File

@@ -8,11 +8,11 @@ for the current state of V***
* [Concurrency](#concurrency)
* [Variable Declarations](#variable-declarations)
* [Strengths](#strengths)
* [Weaknesses](#weaknesses)
* [Compatibility](#compatibility)
* [Automatic Lock](#automatic-lock)
* [Channels](#channels)
* [Strengths](#strengths)
* [Weaknesses](#weaknesses)
* [Compatibility](#compatibility)
* [Automatic Lock](#automatic-lock)
* [Channels](#channels)
## Concurrency
@@ -47,7 +47,7 @@ atomic d := ...
...
}
```
```v ignore
rlock c {
// read c
@@ -65,46 +65,56 @@ atomic d := ...
To help making the correct decision the following table summarizes the
different capabilities:
| | *default* | `mut` | `shared` | `atomic` |
| :--- | :---: | :---: | :---: | :---: |
| write access | | + | + | + |
| concurrent access | + | | + | + |
| performance | ++ | ++ | | + |
| sophisticated operations | + | + | + | |
| structured data types | + | + | + | |
| | *default* | `mut` | `shared` | `atomic` |
|:-------------------------|:---------:|:-----:|:--------:|:--------:|
| write access | | + | + | + |
| concurrent access | + | | + | + |
| performance | ++ | ++ | | + |
| sophisticated operations | + | + | + | |
| structured data types | + | + | + | |
### Strengths
**default**
- very fast
- unlimited access from different coroutines
- easy to handle
**`mut`**
- very fast
- easy to handle
**`shared`**
- concurrent access from different coroutines
- data type may be complex structure
- sophisticated access possible (several statements within one `lock`
block)
**`atomic`**
- concurrent access from different coroutines
- reasonably fast
### Weaknesses
**default**
- read only
**`mut`**
- access only from one coroutine at a time
**`shared`**
- lock/unlock are slow
- moderately difficult to handle (needs `lock` block)
**`atomic`**
- limited to single (max. 64 bit) integers (and pointers)
- only a small set of predefined operations possible
- very difficult to handle correctly
@@ -118,6 +128,7 @@ allocation would be an unnecessary overhead. Instead the compiler
creates a global.
### Compatibility
Outside of `lock`/`rlock` blocks function arguments must in general
match - with the familiar exception that objects declared `mut` can be
used to call functions expecting immutable arguments:
@@ -145,6 +156,7 @@ i(atomic d)
Inside a `lock c {...}` block `c` behaves like a `mut`,
inside an `rlock c {...}` block like an immutable:
```v ignore
shared c := St{...}
lock c {
@@ -160,6 +172,7 @@ rlock c {
```
### Automatic Lock
In general the compiler will generate an error message when a `shared`
object is accessed outside of any corresponding `lock`/`rlock`
block. However in simple and obvious cases the necessary lock/unlock

View File

@@ -13,11 +13,12 @@ provides V language support for Visual Studio Code.
![Screenshot Code with activated extension](https://github.com/vlang/vscode-vlang/raw/HEAD/images/demo.png)
**Features:**
* Syntax Highlighting.
* Code Snippets for quick coding.
* Format code on file save as well as format manually (using v fmt).
* Linter (Workspace files only).
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
**Hint:** This extension will not add the V compiler! Information on how to
[install V compiler](https://github.com/vlang/v/blob/master/doc/docs.md#install-from-source)
@@ -35,31 +36,35 @@ The [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vsc
for Visual Studio Code provides visual conditional debugging.
**Features:**
* Conditional breakpoints
* Function breakpoints
* Expression evaluation
* Change Values
[more Features & Documentation](https://code.visualstudio.com/docs/cpp/cpp-debug)
[more Features & Documentation](https://code.visualstudio.com/docs/cpp/cpp-debug)
**Hint:** Not all types (e.g. Array) in V currently create the required
[DWARF](https://en.wikipedia.org/wiki/DWARF) information to show and
[DWARF](https://en.wikipedia.org/wiki/DWARF) information to show and
edit the variable.
### Setup Debugging
#### Step1: Configure the launch.json file
1. Install the [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
1. Install the
[C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
2. Open `RUN AND DEBUG` panel (Debug Icon in left panel).
3. Click on `Show` all automatic debug configurations.
4. Select `Add config`.
5. Select environment `C++ (GDB/LLDB)`.
6. Change the line `"program": "Enter the program name, e.g. \"${workspaceFolder}/a.out\"",`
to point to your compiled application e.g. `"program": "${workspaceFolder}/hello",`
or a more flexible one `"program": "${fileDirname}/${fileBasenameNoExtension}",`
when you want to debug the current opened file.
to point to your compiled application e.g. `"program": "${workspaceFolder}/hello",`
or a more flexible one `"program": "${fileDirname}/${fileBasenameNoExtension}",`
when you want to debug the current opened file.
This will add a block to your `.workspace` file,
or create the file `.vscode/launch.json`:
```json
{
// Use IntelliSense to learn about possible attributes.
@@ -85,10 +90,11 @@ or create the file `.vscode/launch.json`:
}
```
**Optional:** use `"program": "${fileDirname}/${fileBasenameNoExtension}"` to debug
**Optional:** use `"program": "${fileDirname}/${fileBasenameNoExtension}"` to debug
any current open source file with an existing binary with the same name but without any extension.
#### Step2: Configure the tasks.json file
Generally, you can manually compile the application with: `v -b c -g hello.v -o hello`,
or for short: `v -g hello.v`, and then call the debugger.
@@ -96,14 +102,15 @@ The `-g` option will add the needed debugging information.
You can find more debugging options in the [docs](docs.md#debugging).
VS Code provides a hook called `preLaunchTask`, which can be used to compile
the application automatically every time you call the debugger.
the application automatically every time you call the debugger.
[preLaunchTask](https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes) launches
a task before the start of a debug session, set this attribute to the label of a task specified
in [task.json](https://code.visualstudio.com/docs/editor/tasks) (in the workspace's .vscode folder).
Or, this can be set to `${defaultBuildTask}`, to use your default build task.
As explained, the `"preLaunchTask": "build"` needs to work with a `.vscode/tasks.json`
with a label named `build`.
with a label named `build`.
```json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
@@ -136,7 +143,7 @@ The application needs to include additional debugging information
1. Open your source code and set the required break points
2. Click on the Debug Icon in the left Icon panel and click
`> (lldb) Start`, or use `F5` to launch your application in debug mode.
`> (lldb) Start`, or use `F5` to launch your application in debug mode.
For all options look at the official
For all options look at the official
[C/C++ Extension documentation](https://code.visualstudio.com/docs/cpp/cpp-debug).