Reference casting¶
Ü allows to convert references of one type into references of another type - explicitly or implicitly.
Mutability conversion¶
A mutable (mut
) reference may be converted into immutable (imut
) reference.
fn Bar( i32 &imut x );
struct S{ i32 &imut r; }
fn Foo()
{
var i32 mut x= 0;
var i32 &mut r= x;
Bar( r ); // Implicit conversion of mutable reference "r" into immutable reference - function argument.
var S s{ .r= r }; // Implicit conversion of mutable reference "r" into immutable reference - struct member.
var i32 &imut r2= r;// Implicit conversion of mutable reference "r" into immutable local reference.
}
Conversion into a reference to parent type¶
It’s possible to convert a reference of polymorph class type into reference to any of its ancestors.
class A interface {}
class B interface : A {}
class C polymorph {}
class D : C, B {}
fn FooA( A& a );
fn FooB( B& b );
fn FooC( C& c );
fn Foo()
{
var D d;
FooA(d); // Convert "d" reference into reference to indirect parent (grandparent).
FooB(d); // Convert "d" reference into reference to an implemented interface.
FooC(d); // Convert "d" reference into reference to base class.
}
Explicit reference conversions¶
Sometimes it’s necessary to convert a reference explicitly. Special conversion operators exist for that.
cast_ref
operator is used for explicit reference type conversion.
Destination type should be specified.
class A polymorph {}
class B : A {}
fn Foo( A& a );
fn Foo( B& b );
fn Foo()
{
var B b;
Foo( cast_ref</ A />(b) ); // "b" reference will be converted to reference of type "A" and than "fn Foo( A& a )" will be called.
}
cast_imut
operator is used for mutable to immutable references conversion.
fn Foo( i32 &mut i );
fn Foo( i32 &imut i );
fn Foo()
{
var i32 mut x=0;
Foo( cast_imut(x) ); // Mutable reference to "x" will be converted into immutable reference, than "fn Foo( i32 &imut i )" will be called.
var i32 imut y= 0;
var i32 &imut y_ref= cast_imut(y); // "cast_imut" operator in this case will leave reference immutable.
}
cast_ref_unsafe
is almost like cast_ref
operator, but it allows to perform conversions between unrelated types.
Because of that it may be used only in unsafe
code.
fn Foo()
{
var i32 mut x= 0;
unsafe
{
var void &x_ref_v= cast_ref_unsafe</void/>(x); // Reference to "i32" will be converted into "void" reference
var i32 &x_ref_i= cast_ref_unsafe</i32/>(x_ref_v); // Reference to "void" will be converted into "i32" reference
}
}
cast_mut
operator is used for immutable to mutable reference conversions.
It may be used only in unsafe
code.
fn Foo()
{
var i32 imut x= 0;
unsafe
{
++ cast_mut(x); // Immutable reference to "x" will be converted into mutable reference, than referenced value will be mutated.
}
}