Top.Mail.Ru
? ?

Entries by tag: rust

о гарантиях

fn helper<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }

/// Turn any `&T` into a `&'static T`. May introduce undefined behavior.
pub fn make_static<'a, T>(input: &'a T) -> &'static T {
    let f: fn(_, &'a T) -> &'static T = helper;
    f(&&(), input)
}

(отсюда)
Не ожидал, что так просто. Безо всякого unsafe берем и превращаем "одолженную" ссылку на временное значение в "вечную", с соответствующими use-after-free последствиями. А просто дырка в borrow checker'e, и давно уже, все никак не залатают.

Tags:

Rust

На днях вышла 1.0.0.alpha, решил наконец приобщиться. Почитал онлайн книжку. Если она не слишком много скрывает, язык довольно маленький и простой, это хорошо. Для начала сделал вариант для недавнего микробенчмарка про маленький интерпретатор. В тот раз добрые люди помогли ускорить наивные решения, так что все времена опустились ниже 1 секунды, что делает замеры менее осмысленными. Тем не менее, вот текущие результаты:

D - 0.40 s (при использовании LDC)
Rust - 0.44 s
OCaml - 0.57 s
Haskell - 0.85 s
(с одной закавыкой - Rust тут 64-битный, все остальные 32-битные, так уж получилось)

Т.к. опыт с Rust'ом у меня пока минимальный, впечатления смутные. Одной фразой - "ML в руках плюсовиков". Видишь знакомый набор из алгебраиков, паттерн-матчинга, лямбд, expression-based syntax, начинаешь писать как на ML, и тут на тебя выпрыгивает наследие С++: а ты здесь это значение насовсем передал (у нас move-семантика по-умолчанию, уж больно нам эта фича из С++ понравилась) или хотел лишь по указателю? Ах по указателю, тогда так и напиши везде, и где принимаешь, и где передаешь. А еще и писать туда хотел? Тогда не забудь при передаче &mut дописать. И это же выскакивает при паттерн-матчинге: вот тут ты поле алгебраика заматчил, тебе его так отдать или по ссылке? А обращаться хорошо с ней будешь?
Причем как-то странно сделано, вот есть структуры и есть туплы, разница между ними довольно косметическая, так? Можем пару значений передать как тупл, а можем как структуру. Сделаем пару одинаковых функций, складывающих два поля:
#[derive(Show)]
struct S { x : i32, y : i32 }

fn eat_struct(s : S) -> i32 { 
  s.x + s.y 
}

fn eat_tuple(t : (i32, i32)) -> i32 { 
  let (x,y) = t;
  x + y
} 

Обе получают аргумент по значению.
Теперь попробуем их повызывать:
fn main() {
  let s = S { x: 1, y : 2 };
  let t = (1, 2);
  let rs = eat_struct(s);
  let rt = eat_tuple(t);
  println!("{} {} {:?} {:?}", rs, rt, s, t);
}

И получаем ошибку:
hi.rs:18:39: 18:40 error: use of moved value: `s`
hi.rs:18   println!("{} {} {:?} {:?}", rs, rt, s, t);
                                               ^

Оказывается, когда мы структуру передали в ту функцию, мы ее отдали насовсем, это был move. А вот тупл скопировался, передача по значению, оригинал остается у вызывающей ф-ии. Неожиданно.

Еще занятный момент. В растовском варианте, что по ссылке выше, есть такое выражение:
1 + (if a[i] > a[j] { evalBlock(a, b1) } else { evalBlock(a, b2) })
Казалось бы, его, как в ML вариантах, можно заменить более простым:
1 + evalBlock(a, if a[i] > a[j] { b1 } else { b2 })
Но не тут-то было. Rust считает, что в первом аргументе evalBlock происходит мутабельное заимствование массива а, а при вычислении второго аргумента имеет место иммутабельное заимствование этого же массива. И хотя аргументы должны быть вычислены до вызова функции, и по времени эти два использования массива не пересекаются никак, Rust считает, что тут два параллельных заимствования, одно из которых мутабельное, что недопустимо.

Буду продолжать наблюдения. В целом штука занятная.

Tags:

Profile

office
thedeemon
Dmitry Popov

Latest Month

April 2026
S M T W T F S
   1234
567891011
12131415161718
19202122232425
2627282930  

Syndicate

RSS Atom

Comments

  • thedeemon
    7 Apr 2026, 19:22
    Спасибо, мне интересно! При случае напишу про ЯП хобби-проект, в котором я участвую, но там до системы типов дело ещё не дошло; я довольно мало времени в неделю ему посвящаю, увы.
  • thedeemon
    6 Apr 2026, 19:20
    Да, сейчас сделано на Racket, но планируется версия на самом себе с компиляцией в WebAssembly.
  • thedeemon
    6 Apr 2026, 19:19
    Функциональный язык с хаскелеподобным синтаксисом, статической типизацией, выводом типов, но не чистый: никаких монад и приседаний для эффектов. Свобода действий в духе Окамла или F#: захотел сделать…
  • thedeemon
    6 Apr 2026, 19:04
    А, на Racket, наверно. Я послал приглашение присоедениться на LinkedIn - на всякий случай.
  • thedeemon
    6 Apr 2026, 18:55
    Здорово - глядя на do-нотацию, наверно - some kind of pure functional, с хорошим type inference? Транслируется в Python или Swift, а на чём транслятор написан? Подожду описания!
Powered by LiveJournal.com
Designed by Lilia Ahner