Небезопасный код¶
Ü по умолчанию не допускает ряд операций, считающимися небезопасными:
явное обращение к конструкторам или деструкторам
обращение к глобальным изменяемым переменным
разыменование сырого указателя
арифметические операции над сырыми указателями
оператор
cast_ref_unsafeоператор
cast_mutинициализатор
ununitializedвызов
unsafeфункции
Если же какая-то из этих операций необходима, её следует обернуть в unsafe блок.
Данный блок состоит из ключевого слова unsafe и бока после него.
В даном блоке разрешены все unsafe операции.
fn Foo()
{
unsafe
{
var i32 mut x= uninitialized;
x= 42;
}
}
Внутри unsafe блока также можно объявить safe блок, чтобы на время запретить небезопасные операции.
fn Bar() unsafe;
fn Foo()
{
unsafe
{
Bar(); // Ок, можно звать "unsafe" функцию
safe
{
Bar(); // Ошибка, здесь звать "unsafe" нельзя
}
Bar(); // Ок, теперь снова можно
}
}
Кроме unsafe блоков существуют также unsafe выражения.
По поведению они схожи с unsafe блоками, но действуют на уровне выражений.
Аналогично с safe блоками существует и safe выражения.
fn Bar() unsafe : i32;
fn Foo()
{
var i32 x= 2 * unsafe(Bar()); // Ок - unsafe контекст распространяется только на вызов unsafe функции.
}
Небезопасные функции¶
Небезопасные функции - функции, которые просто так звать не безопасно и перед вызовом которых обычно требуется соблюсти ряд условий.
Небезопасные функции помечаются ключевым словом unsafe после списка аргументов функции и списка связывания ссылок.
Такие функции можно звать только внутри unsafe блока.
Тело unsafe функции не является unsafe блоком, если внутри неё нужно выполнить небезопасные операции, их нужно обернуть в unsafe блок.
fn Bar( i32 d ) unsafe : i32
{
unsafe
{
var i32 mut x= uninitialized;
x= 100 / d;
return x;
}
}
fn Foo()
{
unsafe
{
Bar( 7 );
}
}