Structs
A structure is a data type that allows you to combine several other data types into one with unique names for each.
Suppose you want to store information about a person. You need to store the name and age.
You can define a Person
struct with two fields: name
and age
:
In V, structures are specified using the struct
keyword.
Each field must have a unique name and type.
To instantiate a struct, use a struct literal:
Fields can be initialized in any order or omitted when they are created.
There is also a short syntax for instantiating structures:
To refer to a structure field, use a dot:
Fields
Access/mutability modifiers
As already described above, structures can have fields. By default, all fields are immutable and private. Privacy means that access to them will be only within the current module.
Fields access modifiers can be changed with pub
and mut
keywords.
In total, there are 5 possible options:
Default field values
All struct fields are zeroed by default during the creation of the struct. Array and map fields are allocated.
To set a default value for a field, use =
after the field type:
Required fields
As already described earlier, when creating an instance of a structure, fields can be omitted.
To mark some fields as required, use [required]
attribute:
Methods
Structs can also have methods. To set them, a special syntax is used:
Before the function name, a new parameter is added called receiver
.
It defines the type of the structure that the method belongs to, as well as the name of the
variable,
through which you can access an instance of the structure on which the method is called.
By convention, the receiver name should not be self
or this
.
It is better to use a short, preferably one-letter, name.
Just like accessing the fields of a structure, a dot is used:
Methods must be declared in the same module as the struct.
Reference receiver
In the example above, we declared the receiver as p Person
.
This means that the method will be called on a copy of the structure.
To call a method on the original structure, you need to use &
before the receiver type:
In this case, an instance of the structure will be passed to the method by reference.
This can be useful for large structures where copying them can be an expensive operation.
Note that although a struct is passed by reference, you cannot change the fields of a struct
within a method, even if they are marked mut
.
Mutable receivers
By default, struct fields cannot be changed in methods, even if the field itself is marked as mut
.
The following code will not be compiled:
To change the fields of a structure in a method, you need to add mut
before the name of the
receiver:
In this case, we can freely change the mutable fields of the structure inside the method. Such methods can only be called on mutable struct instances:
Note that in this case the receiver becomes implicitly referential, i.e.,
its type becomes &Person
instead of Person
.
This means that the structure instance will not be copied when the method
is called, but a pointer to it will be passed.
The
mut p &Person
entry is currently prohibited.
Static methods
Structs can also have static methods. To set them, a special syntax is used:
Static methods are defined for the structure, not for the instance of the structure. This means that you do not need to instantiate the struct to call a static method.
With static methods, you can create separate namespaces for functions that operate on a particular structure.
Using static methods, you can prevent cluttering the module's scope with unnecessary functions that are not required independently from the structure.
Constructors
Unlike other languages, V does not have the concept of constructors. But you can use static methods to simulate a constructor.
By convention, such methods are called new
:
Calling such a method is no different from calling a static method:
See also noinit structs.
Allocate structs on the heap
Structs are allocated on the stack.
To allocate a struct on the heap and get a reference to it, use the &
prefix:
See also Stack and Heap
Always heap allocated structs
For some structures, you may want them to always be allocated on the heap.
You can use attribute [heap]
for this:
Struct update syntax
V provides a convenient syntax for changing the fields of a structure.
The passed structure will be copied, and only those fields specified in the update
syntax after the ...u
will be changed in the copy.
Trailing struct literal arguments
V does not have default function arguments or named arguments, for that trailing struct literal syntax can be used instead:
As you can see, both the struct name and braces can be omitted, instead of:
you can just write:
This only works for functions that take a struct for the last argument.
[params]
attribute 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
[noinit]
structs
V supports [noinit]
structs, which are structs that cannot be initialised outside the module
they are defined in. They are either meant to be used internally or they can be used externally
through factory functions.
For an example, consider the following source in a directory sample
:
Note that new_information
is a factory function.
Now when we want to use this struct outside the module:
See also constructors.
Structs with reference fields
Structs with references require explicitly setting the initial value to a reference value unless the struct already defines its own initial value.
Zero-value references, or nil pointers will NOT be supported in the future,
for now data structures such as Linked Lists or Binary Trees that rely on reference
fields that can use the value 0
, understanding that it is unsafe, and that it can
cause a panic.
Anonymous structs
V supports anonymous structs: structs that do not have to be declared separately with a struct name.