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:
parent
41c85661ef
commit
ce2c732db8
328
doc/docs.md
328
doc/docs.md
@ -136,6 +136,7 @@ To do so, run the command `v up`.
|
||||
* [Package options](#package-options)
|
||||
* [Publish package](#publish-package)
|
||||
* [Advanced Topics](#advanced-topics)
|
||||
* [Attributes](#attributes)
|
||||
* [Memory-unsafe code](#memory-unsafe-code)
|
||||
* [Structs with reference fields](#structs-with-reference-fields)
|
||||
* [sizeof and __offsetof](#sizeof-and-__offsetof)
|
||||
@ -161,7 +162,6 @@ To do so, run the command `v up`.
|
||||
* [Cross compilation](#cross-compilation)
|
||||
* [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v)
|
||||
* [Vsh scripts with no extension](#vsh-scripts-with-no-extension)
|
||||
* [Attributes](#attributes)
|
||||
* [Appendices](#appendices)
|
||||
* [Keywords](#appendix-i-keywords)
|
||||
* [Operators](#appendix-ii-operators)
|
||||
@ -4954,6 +4954,169 @@ Package are up to date.
|
||||
to allow for a better search experience.
|
||||
|
||||
# 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
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user