The sum type is a special data type that can hold a value of one of several types while maintaining type safety.
Suppose you need to describe the width of an element in CSS. It can be specified either as a number of pixels or as a string expression. Of course, the CSS specification is more complex, but we will simplify it for the sake of the example.
To specify the sum type, use the
| lists the types that the sum type will consist of.
Now let us try to use it:
To create a new instance of the sum type, use type casting:
In this case, the expression that is cast to the sum type must be one of the
types listed through
| when declaring the sum type.
Otherwise, there will be a compilation error.
Recursive sum types
The sum type can be recursive, i.e. refer to itself, but only if it is defined as an array or map element type:
Accessing fields from structures in the sum type
If the sum type contains structures, then through the sum type you can access their fields if a field with the same name exists in all structures that are part of the sum type.
Calling methods from structures in sum type
Unlike fields, even if all structures in a sum type have a method with the same name, they cannot be accessed through the sum type!
Get the type of the stored value
Sometimes you need to find out what type is stored in an instance of the sum type.
To do this, for any sum type, the
type_name() method is defined, which returns
the name of the type that is currently stored.
Working with sum type
To conveniently handle the type of the sum, the
match expression can be
used to check the type of the stored value.
At the same time,
match must be exhaustive, that is, handle all possible
variants of the sum type or have an
With sum types, you could build recursive structures:
is operator checks if the value stored in the sum type is of the specified type:
as operator casts the value stored in the sum type to the specified type:
If the value stored in the sum type is not of the specified type, then the program will panic.
Because of this, the
as operator should be used with caution.
Smart casts can be used as a replacement.
The V compiler can automatically type cast inside
In this example,
width is of type
int within the body of the
The compiler understands that inside the
if block, the
width variable is of type
since the condition of the
if block checks that
width is int.
width is a mutable identifier, it would be unsafe if the compiler smart casts it without a
That is why you have to declare a
mut before the
width would keep its original type.
This works for both, simple variables and complex expressions like