Комментарии 16
«С точки зрения» же.
И вообще я не уверен, что это чудесное произведение стоило переводить.
О, я первый… Хорошая статья — веселая :-) Сам пару дней как пробую Rust — и пока чувствую себя одичалым, шагающим по владениям Ланистеров...
Потому что почти все особенности Rust в “современном” C++ (с его rvalue references и
std::move
) тоже есть, только в программе они не прописаны, компилятором не проверяются и зачастую даже тестами не всегда выявляются.Бороться с ними приходится уже тогда, когда всё упало упало у заказчика (ну или с помощью кучки санитайзеров).
Бороться с правилами
Rust
— тоже та ещё разлекуха, но по сравнению с C++ это просто сказка: если компилятор вы убедили, то дело на 90% (если не на 99%) сделано, скорее всего будет работать.Для пробы сделал простой веб бэкэнд для учета расходов с базой в Postgres. В процессе работы я получил много положительных эмоций и опыта. Actix web в простых задачах прост и понятен, Serde можно подключать не полностью, а только необходимые части, есть возможность использовать nanoserde если нужен только json и дорожите размером библиотек.
На самом деле надо просто понимать, когда требования слишком сильные и их можно ослабить В примере со строкой это просто:
let a = String::from("foo");
{
dbg!(&a);
}
dbg!(&a);
dbg!(&a);
для вывода отладочной печати объект уничтожать не обязательно.
Альтернативно (для любителей заюзать линейность):
let a = String::from("foo");
let a = {
dbg!(a);
}
let a = dbg!(a);
let a = dbg!(a);
Статья (оригинальная) оставила смешанное впечатленеи. С одной стороны забавно, а с другой — за ёлками потеряли лес. Ощущения как от статьи объясняющую монады через буритто и коробки.
Сам являюсь (в какой-то степени) Java Script энтузиастом, так что после прочтения аж самому руки зачесались пробовать всякие непотребства с Rust'ом :)
Не только из разных потоков, а в общем случае из разных контекстов. Раст расширяет защиту через четкое владение и на асинхронные приложения, типа тех, что пишут на JS.
То есть я хочу сказать, что не смотря на полную многослойную защиту памяти виртуальной машиной внутри и снаружи, в JS меньше конструкций помогающих избегать неконсистентных состояний.
let a = String::from("foo");
{
dbg!(a);
}
Скоуп здесь ни при чем, a
перемещается в dbg!
, а не внутрь блока. То есть, такой код будет аналогичен:
let a = String::from("foo");
dbg!(a);
```
let a = String::from(«foo»);
dbg!(a); // это inner scope по отношению к main
dbg!(a); // это тоже inner scope по отношению к main
```
Данный код вызовет ошибку, потому что inner scope вернул память системе
```
let a = String::from(«foo»);
a = dbg!(a);
dbg!(a);
```
Этот код не выозвет ошибку, т.к. inner scope вернул память main scope.
```
let a = String::from(«foo»);
{ // inner scope
let b = String::from(«bar»);
println!(«Я не владею {}», a);
println!(«Зато владею {}», b);
}
dbg!(a);
dbg!(b);
```
Этот код приведет к ошибке владения b, но не как не a. Т.к. inner scope не владеет а. А b как раз создана во владениях inner scope и буде тудалена когда inner scope закончится (на символе })
Юмористичный обзор Rust с перспективы JavaScript