Чуть-чуть о статье
Теперь попробуем создать что-то вроде «глобальной переменной» с помощью ключевого слова static.
«Они похожи на постоянные, но статические значения не встраиваются в место их использования. Это значит, что каждое значение существует в единственном экземпляре, и у него есть определённый адрес».
Объявим её:
static N = 8;
fn main() {
println!("N = {}",N);
}
Компилируем. Выход:
error: expected ':', found '='
static N = 8;
~~~~~~~^
Как видно, нам и в этом случае необходимо указывать тип. Исправляем:
static N: i32 = 8;
И у нас всё в порядке. Выход:
N = 8
Пробуем так:
static N: i32 = 4;
static N: i32 = 5;
fn main() {
println!("N = {}",N);
}
Выход:
error: duplicate definition of value `N` [E0428]
Так же как и с константами. Ясно. Продолжаем делать всё, что делали с константами:
static N: i32 = 4;
fn main() {
println!("N = {}",N);
static N: i32 = 8;
println!("N = {}",N);
}
Выход:
warning: static item is never used: `N`, #[warn(dead_code)] on by default
static N: i32 = 4;
^~~~~~~~~~~~~~~~~
Так же как и с константами. Пробуем дальше:
static N: i32 = 4;
fn main() {
println!("N = {}",N);
static N: i32 = 8;
println!("N = {}n",N);
other();
}
fn other() {
println!("N = {}",N);
}
Выход:
N = 8
N = 8
N = 4
Далее:
static N: i32 = 4;
fn main() {
println!("N = {}",N);
static M: i32 = 8;
println!("M = {}n",M);
other();
}
fn other() {
println!("N = {}",N);
}
То выход будет таким:
N = 4
M = 8
N = 4
И ещё один эксперимент:
fn main() {
println!("N = {}",N);
static N: i32 = 8;
static N: i32 = 9;
println!("N = {}n",N);
}
Выход:
error: duplicate definition of value `N` [E0428]
static N: i32 = 9;
^~~~~~~~~~~~~~~~~
Следующий:
fn main() {
println!("N = {}",N);
static N: i32 = 8;
{
static N: i32 = 9;
}
println!("N = {}n",N);
}
Выход:
N = 8
N = 8
Можно и так:
fn main() {
println!("N = {}",N);
static N: i32 = 8;
{
println!("N = {}n",N);
}
println!("N = {}n",N);
}
Выход:
N = 8
N = 8
N = 8
А если так:
fn main() {
println!("N = {}",N);
{
static N: i32 = 8;
println!("N = {}n",N);
}
println!("N = {}n",N);
}
Выход:
error: unresolved name `N` [E0425]
println!(«N = {}»,N);
~~~~~~~~~~~~^
...
Ещё:
static N: i32 = 3;
fn main() {
println!("N = {}",N);
{
static N: i32 = 8;
println!("N = {}n",N);
}
println!("N = {}n",N);
}
Выход:
N = 3
N = 8
N = 3
Короче, здесь всё было как с константами. Попробуем сделать переменную изменяемой:
fn main() {
println!("{} = n",N);
static mut N: i32 = 8;
}
Выход:
error: use of mutable static requires unsafe function or block [E0133]
println!("{} = N",N);
Говорит, типо, это слишком небезопасно.
«По скольку N изменяемо, один поток может изменить его во время того, как другой читает его значение. Это ситуация «гонки» по данным, и она считается небезопасным поведением в Rust. Поэтому и чтение, и изменение статическ ого изменяемого зна чения( static mut ) является небезопасным (unsafe), и обе эти операции должны выполняться в небезопасных блоках ( unsafe block)».
Поэтому делаем так:
fn main() {
unsafe {
println!("{} = N",N);
}
static mut N: i32 = 8;
}
Выход:
8 = N
Можем сделать так:
fn main() {
unsafe {
println!("{} = n",N);
static mut N: i32 = 8;
}
println!("{} = n",N);
}
Но тогда N не будет видно для второго println!(...). Нам вернут ошибку:
error: unresolved name 'N' [E0425]
println!("{} = N",N);
Если сделать её глобальной, то работает:
static mut N: i32 = 8;
fn main() {
unsafe {
println!("{} = n",N);
}
}
Выход:
8 = N
Теперь ссылки.
«Каждое значение существует в единственном экземпляре, и у него есть определённый адрес. Статические зна чения живут в течение всего времени работы программы, и любая ссылка
на постоянную имеет статическ ое время жизни ( static lifetime)».
static N: i32 = 8
fn main() {
let x = &N;
println!("{} = N",N);
println!("{} = N",*x);
println!("{:p} -> N",&N);
println!("{:p} -> N",x);
}
Выход:
N = 8
N = 8
0x8010b884 -> N
0x8010b884 -> N
Ну, там ещё есть такое:
«Более того, любой тип, хранимый в статическ ой переменной, должен быть ограничен
Sync и не может иметь реализации Drop ».
Но я не знаю что это значит и буду очень рад, если кто-то зкажет, что это значит…
Литература:
The Rust Reference (английский)
The Rust Programming Language (английский)
The Rust Programming Language (русский)
Автор: no_face