Преобразование ссылок¶
Ü позволяет преобразовывать ссылки одного вида в ссылки другого вида, явным или неявным образом.
Преобразование изменяемости¶
Изменяемую (mut
) ссылку можно неявно преобразовать в неизменяемую (imut
) ссылку.
fn Bar( i32 &imut x );
struct S{ i32 &imut r; }
fn Foo()
{
var i32 mut x= 0;
var i32 &mut r= x;
Bar( r ); // Неявное преобразование изменяемой ссылки "r" в неизменяемую ссылку - аргумент функции.
var S s{ .r= r }; // Неявное преобразование изменяемой ссылки "r" в неизменяемую ссылку - поле структуры.
var i32 &imut r2= r;// Неявное преобразование изменяемой ссылки "r" в неизменяемую локальную ссылку.
}
Преобразование в ссылку на предковый тип¶
Ссылку на полиморфный класс возможно преобразовать в ссылку на любого из его предков.
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); // Преобразование ссылки в ссылку на непрямого предка (дедушку).
FooB(d); // Преобразование ссылки в ссылку на реализуемый интерфейс.
FooC(d); // Преобразование ссылки в ссылку на базовый класс.
}
Явные преобразования ссылок¶
Иногда бывает необходимо явно преобразовать ссылку. Для этих целей служат операторы явного преобразования.
Оператор cast_ref
используется для явного преобразования типа ссылки. Для этого оператора надо указать тип назначения.
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" будет преобразована в ссылку на "A", после чего вызовется функция fn Foo( A& a );
}
Оператор cast_imut
используется для преобразования изменяемых ссылок в неизменяемые.
fn Foo( i32 &mut i );
fn Foo( i32 &imut i );
fn Foo()
{
var i32 mut x=0;
Foo( cast_imut(x) ); // Изменяемая ссылка на "x" будет преобразована неизменяемую ссылку, после чего вызовется функция fn Foo( i32 &imut i );
var i32 imut y= 0;
var i32 &imut y_ref= cast_imut(y); // Оператор "cast_imut" в данном случае оставит модификатор изменяемойсти ссылки, т. к. выражение внутри него - неизменяемая ссылка.
}
Оператор cast_ref_unsafe
, аналогично оператору cast_ref
, используется для явного преобразования типа ссылки.
Но в отличие от последнего им можно преобразовать ссылку в неродственный тип. Из-за этого данный оператор можно использовать только в unsafe
коде.
fn Foo()
{
var i32 mut x= 0;
unsafe
{
var void &x_ref_v= cast_ref_unsafe</void/>(x); // Ссылка на "i32" пребразована в ссылку на "void"
var i32 &x_ref_i= cast_ref_unsafe</i32/>(x_ref_v); // Ссылка на "void" пребразована в ссылку на "i32"
}
}
Оператор cast_mut
, используется для преобразования неизменяемых ссылок в изменяемые.
Использовать этот оператор можно только в unsafe
коде.
fn Foo()
{
var i32 imut x= 0;
unsafe
{
++ cast_mut(x); // Неизменяемая ссылка на "x" преобразуется в изменяемую ссылку, с помощью которой изменяется значение, на которое указывает ссылка.
}
}