mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
doc: move the Attributes subsection at the start of its parent section (#16183)
This commit is contained in:
328
doc/docs.md
328
doc/docs.md
@@ -136,6 +136,7 @@ To do so, run the command `v up`.
|
|||||||
* [Package options](#package-options)
|
* [Package options](#package-options)
|
||||||
* [Publish package](#publish-package)
|
* [Publish package](#publish-package)
|
||||||
* [Advanced Topics](#advanced-topics)
|
* [Advanced Topics](#advanced-topics)
|
||||||
|
* [Attributes](#attributes)
|
||||||
* [Memory-unsafe code](#memory-unsafe-code)
|
* [Memory-unsafe code](#memory-unsafe-code)
|
||||||
* [Structs with reference fields](#structs-with-reference-fields)
|
* [Structs with reference fields](#structs-with-reference-fields)
|
||||||
* [sizeof and __offsetof](#sizeof-and-__offsetof)
|
* [sizeof and __offsetof](#sizeof-and-__offsetof)
|
||||||
@@ -161,7 +162,6 @@ To do so, run the command `v up`.
|
|||||||
* [Cross compilation](#cross-compilation)
|
* [Cross compilation](#cross-compilation)
|
||||||
* [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v)
|
* [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v)
|
||||||
* [Vsh scripts with no extension](#vsh-scripts-with-no-extension)
|
* [Vsh scripts with no extension](#vsh-scripts-with-no-extension)
|
||||||
* [Attributes](#attributes)
|
|
||||||
* [Appendices](#appendices)
|
* [Appendices](#appendices)
|
||||||
* [Keywords](#appendix-i-keywords)
|
* [Keywords](#appendix-i-keywords)
|
||||||
* [Operators](#appendix-ii-operators)
|
* [Operators](#appendix-ii-operators)
|
||||||
@@ -4954,6 +4954,169 @@ Package are up to date.
|
|||||||
to allow for a better search experience.
|
to allow for a better search experience.
|
||||||
|
|
||||||
# Advanced Topics
|
# Advanced Topics
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
V has several attributes that modify the behavior of functions and structs.
|
||||||
|
|
||||||
|
An attribute is a compiler instruction specified inside `[]` right before a
|
||||||
|
function/struct/enum declaration and applies only to the following declaration.
|
||||||
|
|
||||||
|
```v
|
||||||
|
// [flag] enables Enum types to be used as bitfields
|
||||||
|
|
||||||
|
[flag]
|
||||||
|
enum BitField {
|
||||||
|
read
|
||||||
|
write
|
||||||
|
other
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert 1 == int(BitField.read)
|
||||||
|
assert 2 == int(BitField.write)
|
||||||
|
mut bf := BitField.read
|
||||||
|
assert bf.has(.read | .other) // test if *at least one* of the flags is set
|
||||||
|
assert !bf.all(.read | .other) // test if *all* of the flags is set
|
||||||
|
bf.set(.write | .other)
|
||||||
|
assert bf.has(.read | .write | .other)
|
||||||
|
assert bf.all(.read | .write | .other)
|
||||||
|
bf.toggle(.other)
|
||||||
|
assert bf == BitField.read | .write
|
||||||
|
assert bf.all(.read | .write)
|
||||||
|
assert !bf.has(.other)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Struct field deprecations:
|
||||||
|
```v oksyntax
|
||||||
|
module abc
|
||||||
|
|
||||||
|
// Note that only *direct* accesses to Xyz.d in *other modules*, will produce deprecation notices/warnings:
|
||||||
|
pub struct Xyz {
|
||||||
|
pub mut:
|
||||||
|
a int
|
||||||
|
d int [deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01']
|
||||||
|
// the tags above, will produce a notice, since the deprecation date is in the far future
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Function/method deprecations:
|
||||||
|
```v
|
||||||
|
// Calling this function will result in a deprecation warning
|
||||||
|
[deprecated]
|
||||||
|
fn old_function() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// It can also display a custom deprecation message
|
||||||
|
[deprecated: 'use new_function() instead']
|
||||||
|
fn legacy_function() {}
|
||||||
|
|
||||||
|
// You can also specify a date, after which the function will be
|
||||||
|
// considered deprecated. Before that date, calls to the function
|
||||||
|
// will be compiler notices - you will see them, but the compilation
|
||||||
|
// is not affected. After that date, calls will become warnings,
|
||||||
|
// so ordinary compiling will still work, but compiling with -prod
|
||||||
|
// will not (all warnings are treated like errors with -prod).
|
||||||
|
// 6 months after the deprecation date, calls will be hard
|
||||||
|
// compiler errors.
|
||||||
|
[deprecated: 'use new_function2() instead']
|
||||||
|
[deprecated_after: '2021-05-27']
|
||||||
|
fn legacy_function2() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```v nofmt
|
||||||
|
// This function's calls will be inlined.
|
||||||
|
[inline]
|
||||||
|
fn inlined_function() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function's calls will NOT be inlined.
|
||||||
|
[noinline]
|
||||||
|
fn function() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function will NOT return to its callers.
|
||||||
|
// Such functions can be used at the end of or blocks,
|
||||||
|
// just like exit/1 or panic/1. Such functions can not
|
||||||
|
// have return types, and should end either in for{}, or
|
||||||
|
// by calling other `[noreturn]` functions.
|
||||||
|
[noreturn]
|
||||||
|
fn forever() {
|
||||||
|
for {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following struct must be allocated on the heap. Therefore, it can only be used as a
|
||||||
|
// reference (`&Window`) or inside another reference (`&OuterStruct{ Window{...} }`).
|
||||||
|
// See section "Stack and Heap"
|
||||||
|
[heap]
|
||||||
|
struct Window {
|
||||||
|
}
|
||||||
|
|
||||||
|
// V will not generate this function and all its calls if the provided flag is false.
|
||||||
|
// To use a flag, use `v -d flag`
|
||||||
|
[if debug]
|
||||||
|
fn foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
foo() // will not be called if `-d debug` is not passed
|
||||||
|
}
|
||||||
|
|
||||||
|
// The memory pointed to by the pointer arguments of this function will not be
|
||||||
|
// freed by the garbage collector (if in use) before the function returns
|
||||||
|
[keep_args_alive]
|
||||||
|
fn C.my_external_function(voidptr, int, voidptr) int
|
||||||
|
|
||||||
|
// Calls to following function must be in unsafe{} blocks.
|
||||||
|
// Note that the code in the body of `risky_business()` will still be
|
||||||
|
// checked, unless you also wrap it in `unsafe {}` blocks.
|
||||||
|
// This is useful, when you want to have an `[unsafe]` function that
|
||||||
|
// has checks before/after a certain unsafe operation, that will still
|
||||||
|
// benefit from V's safety features.
|
||||||
|
[unsafe]
|
||||||
|
fn risky_business() {
|
||||||
|
// code that will be checked, perhaps checking pre conditions
|
||||||
|
unsafe {
|
||||||
|
// code that *will not be* checked, like pointer arithmetic,
|
||||||
|
// accessing union fields, calling other `[unsafe]` fns, etc...
|
||||||
|
// Usually, it is a good idea to try minimizing code wrapped
|
||||||
|
// in unsafe{} as much as possible.
|
||||||
|
// See also [Memory-unsafe code](#memory-unsafe-code)
|
||||||
|
}
|
||||||
|
// code that will be checked, perhaps checking post conditions and/or
|
||||||
|
// keeping invariants
|
||||||
|
}
|
||||||
|
|
||||||
|
// V's autofree engine will not take care of memory management in this function.
|
||||||
|
// You will have the responsibility to free memory manually yourself in it.
|
||||||
|
[manualfree]
|
||||||
|
fn custom_allocations() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// For C interop only, tells V that the following struct is defined with `typedef struct` in C
|
||||||
|
[typedef]
|
||||||
|
struct C.Foo {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to add a custom calling convention to a function, available calling convention: stdcall, fastcall and cdecl.
|
||||||
|
// This list aslo apply for type aliases (see below).
|
||||||
|
[callconv: "stdcall"]
|
||||||
|
fn C.DefWindowProc(hwnd int, msg int, lparam int, wparam int)
|
||||||
|
|
||||||
|
// Used to add a custom calling convention to a function type aliases.
|
||||||
|
[callconv: "fastcall"]
|
||||||
|
type FastFn = fn (int) bool
|
||||||
|
|
||||||
|
// Windows only:
|
||||||
|
// Without this attribute all graphical apps will have the following behavior on Windows:
|
||||||
|
// If run from a console or terminal; keep the terminal open so all (e)println statements can be viewed.
|
||||||
|
// If run from e.g. Explorer, by double-click; app is opened, but no terminal is opened, and no (e)println output can be seen.
|
||||||
|
// Use it to force-open a terminal to view output in, even if the app is started from Explorer.
|
||||||
|
// Valid before main() only.
|
||||||
|
[console]
|
||||||
|
fn main() {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Memory-unsafe code
|
## Memory-unsafe code
|
||||||
|
|
||||||
@@ -6131,169 +6294,6 @@ were made and keep the binary as `tmp.<scriptfilename>`. **Caution**: if this fi
|
|||||||
exists the file will be overriden. If you want to rebuild each time and not keep this binary instead
|
exists the file will be overriden. If you want to rebuild each time and not keep this binary instead
|
||||||
use `#!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp run`.
|
use `#!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp run`.
|
||||||
|
|
||||||
## Attributes
|
|
||||||
|
|
||||||
V has several attributes that modify the behavior of functions and structs.
|
|
||||||
|
|
||||||
An attribute is a compiler instruction specified inside `[]` right before a
|
|
||||||
function/struct/enum declaration and applies only to the following declaration.
|
|
||||||
|
|
||||||
```v
|
|
||||||
// [flag] enables Enum types to be used as bitfields
|
|
||||||
|
|
||||||
[flag]
|
|
||||||
enum BitField {
|
|
||||||
read
|
|
||||||
write
|
|
||||||
other
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
assert 1 == int(BitField.read)
|
|
||||||
assert 2 == int(BitField.write)
|
|
||||||
mut bf := BitField.read
|
|
||||||
assert bf.has(.read | .other) // test if *at least one* of the flags is set
|
|
||||||
assert !bf.all(.read | .other) // test if *all* of the flags is set
|
|
||||||
bf.set(.write | .other)
|
|
||||||
assert bf.has(.read | .write | .other)
|
|
||||||
assert bf.all(.read | .write | .other)
|
|
||||||
bf.toggle(.other)
|
|
||||||
assert bf == BitField.read | .write
|
|
||||||
assert bf.all(.read | .write)
|
|
||||||
assert !bf.has(.other)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Struct field deprecations:
|
|
||||||
```v oksyntax
|
|
||||||
module abc
|
|
||||||
|
|
||||||
// Note that only *direct* accesses to Xyz.d in *other modules*, will produce deprecation notices/warnings:
|
|
||||||
pub struct Xyz {
|
|
||||||
pub mut:
|
|
||||||
a int
|
|
||||||
d int [deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01']
|
|
||||||
// the tags above, will produce a notice, since the deprecation date is in the far future
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Function/method deprecations:
|
|
||||||
```v
|
|
||||||
// Calling this function will result in a deprecation warning
|
|
||||||
[deprecated]
|
|
||||||
fn old_function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// It can also display a custom deprecation message
|
|
||||||
[deprecated: 'use new_function() instead']
|
|
||||||
fn legacy_function() {}
|
|
||||||
|
|
||||||
// You can also specify a date, after which the function will be
|
|
||||||
// considered deprecated. Before that date, calls to the function
|
|
||||||
// will be compiler notices - you will see them, but the compilation
|
|
||||||
// is not affected. After that date, calls will become warnings,
|
|
||||||
// so ordinary compiling will still work, but compiling with -prod
|
|
||||||
// will not (all warnings are treated like errors with -prod).
|
|
||||||
// 6 months after the deprecation date, calls will be hard
|
|
||||||
// compiler errors.
|
|
||||||
[deprecated: 'use new_function2() instead']
|
|
||||||
[deprecated_after: '2021-05-27']
|
|
||||||
fn legacy_function2() {}
|
|
||||||
```
|
|
||||||
|
|
||||||
```v nofmt
|
|
||||||
// This function's calls will be inlined.
|
|
||||||
[inline]
|
|
||||||
fn inlined_function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function's calls will NOT be inlined.
|
|
||||||
[noinline]
|
|
||||||
fn function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function will NOT return to its callers.
|
|
||||||
// Such functions can be used at the end of or blocks,
|
|
||||||
// just like exit/1 or panic/1. Such functions can not
|
|
||||||
// have return types, and should end either in for{}, or
|
|
||||||
// by calling other `[noreturn]` functions.
|
|
||||||
[noreturn]
|
|
||||||
fn forever() {
|
|
||||||
for {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following struct must be allocated on the heap. Therefore, it can only be used as a
|
|
||||||
// reference (`&Window`) or inside another reference (`&OuterStruct{ Window{...} }`).
|
|
||||||
// See section "Stack and Heap"
|
|
||||||
[heap]
|
|
||||||
struct Window {
|
|
||||||
}
|
|
||||||
|
|
||||||
// V will not generate this function and all its calls if the provided flag is false.
|
|
||||||
// To use a flag, use `v -d flag`
|
|
||||||
[if debug]
|
|
||||||
fn foo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bar() {
|
|
||||||
foo() // will not be called if `-d debug` is not passed
|
|
||||||
}
|
|
||||||
|
|
||||||
// The memory pointed to by the pointer arguments of this function will not be
|
|
||||||
// freed by the garbage collector (if in use) before the function returns
|
|
||||||
[keep_args_alive]
|
|
||||||
fn C.my_external_function(voidptr, int, voidptr) int
|
|
||||||
|
|
||||||
// Calls to following function must be in unsafe{} blocks.
|
|
||||||
// Note that the code in the body of `risky_business()` will still be
|
|
||||||
// checked, unless you also wrap it in `unsafe {}` blocks.
|
|
||||||
// This is useful, when you want to have an `[unsafe]` function that
|
|
||||||
// has checks before/after a certain unsafe operation, that will still
|
|
||||||
// benefit from V's safety features.
|
|
||||||
[unsafe]
|
|
||||||
fn risky_business() {
|
|
||||||
// code that will be checked, perhaps checking pre conditions
|
|
||||||
unsafe {
|
|
||||||
// code that *will not be* checked, like pointer arithmetic,
|
|
||||||
// accessing union fields, calling other `[unsafe]` fns, etc...
|
|
||||||
// Usually, it is a good idea to try minimizing code wrapped
|
|
||||||
// in unsafe{} as much as possible.
|
|
||||||
// See also [Memory-unsafe code](#memory-unsafe-code)
|
|
||||||
}
|
|
||||||
// code that will be checked, perhaps checking post conditions and/or
|
|
||||||
// keeping invariants
|
|
||||||
}
|
|
||||||
|
|
||||||
// V's autofree engine will not take care of memory management in this function.
|
|
||||||
// You will have the responsibility to free memory manually yourself in it.
|
|
||||||
[manualfree]
|
|
||||||
fn custom_allocations() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// For C interop only, tells V that the following struct is defined with `typedef struct` in C
|
|
||||||
[typedef]
|
|
||||||
struct C.Foo {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used to add a custom calling convention to a function, available calling convention: stdcall, fastcall and cdecl.
|
|
||||||
// This list aslo apply for type aliases (see below).
|
|
||||||
[callconv: "stdcall"]
|
|
||||||
fn C.DefWindowProc(hwnd int, msg int, lparam int, wparam int)
|
|
||||||
|
|
||||||
// Used to add a custom calling convention to a function type aliases.
|
|
||||||
[callconv: "fastcall"]
|
|
||||||
type FastFn = fn (int) bool
|
|
||||||
|
|
||||||
// Windows only:
|
|
||||||
// Without this attribute all graphical apps will have the following behavior on Windows:
|
|
||||||
// If run from a console or terminal; keep the terminal open so all (e)println statements can be viewed.
|
|
||||||
// If run from e.g. Explorer, by double-click; app is opened, but no terminal is opened, and no (e)println output can be seen.
|
|
||||||
// Use it to force-open a terminal to view output in, even if the app is started from Explorer.
|
|
||||||
// Valid before main() only.
|
|
||||||
[console]
|
|
||||||
fn main() {
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Appendices
|
# Appendices
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user