All streams
Search
Write a publication
Pull to refresh
88
0
Александр Мещеряков @freecoder_xx

Rust разработчик

Send message

Почему бы просто не использовать Rc?


fn annotate<'a>(input: &'a String, type_name: &str) -> Rc<dyn Object + 'a> {
    Rc::new(Wrapper {
        value: input,
        type_name: type_name.into(),
    })
}
В примере выше используется assert_eq, а не обычный assert )
"Отвалилось на 10 строчке" и ищи свищи

Не только. Еще будет распечатано содержимое assert'а (если использовался обычный assert).

HKT в Rust пока нет (
С помощью типажей можно нечто подобное сымитировать, но это ограниченный и малопонятный подход.


Обычно используется простое решение с Option, но оно не даст статических гарантий отсутствия значения:


#[derive(PartialEq, PartialOrd, Debug)]
struct Struct {
    name: String,
    age: i32,
    salary: i32,
    dept: Option<String>,
    smth_else: Option<i32>,
}

let reduced = Struct { name: "meh".to_string(), age: 20, salary: 42, dept: None, smth_else: None };
let full = Struct { name: "meh".to_string(), age: 20, salary: 42, dept: Some("IT".to_string()), smth_else: Some(10) };

Здесь reduced и full будут одного и того же типа, со всеми вытекающими.

Этот пример показывает, что в Rust есть встроенная поддержка базовых механизмов тестирования, и что тесты писать очень просто. Большинство тестов именно так и пишутся. Если вам нужны моки, или рандомная генерация тестовых наборов, или еще что-то дополнительно — всегда можно использовать внешние библиотеки для этого. Но опять же, чаще вам нужно просто удостовериться, что ваша функция (или метод) корректно работают на нескольких основных и крайних значениях. Легковесные тесты тут выручают и вас, и тех, кто потом будет читать ваш код, так как они сразу получат примеры его использования.
Из тех, что я видел — пребывают в заброшенном состоянии. Сейчас, видимо, период практических экспериментов, теоретические осмысления появятся позже. Поэтому приходится высматривать паттерны в исходных кодах популярных библиотек.
Rust все-таки императивный язык программирования. Он этим и интересен, что привносит в императивное программирование многое из того, что раньше было доступно лишь в функциональных языках. При этом позволяя писать и низкоуровневые вещи, а также не жертвуя эффективностью, с околонулевой стоимостью абстракций и автоматическим управлением памятью без сборки мусора.

Раньше были опасения, что Rust может сильно отстать от Go и Swift из-за отсутствия маркетинговой раскрутки. Но сейчас таких опасений нет, Rust хорошо развивается как язык, появляется все больше интересных проектов, его сообщество постоянно растет. Лично я считаю, что Rust — сильно недооцененная технология. Это "мина замедленного действия", "подрыв" которой — вопрос времени.

Примеры можно посмотреть здесь.

1) Где вам нужно наследовать данные — агрегация всегда применима, разве нет? Другое дело, что если таким образом имитировать наследование в стиле ООП, то придется писать много дополнительного кода с пробросом вызова методов. Но так писать не надо ) Я стараюсь просто избегать раздувания структур и создания больших иерархий. Лучше создавать больше маленьких типов, активнее пользоваться типажами и средствами обобщенного программирования. Проблема с этим была только в самом начале, когда я пытался писать на Rust в стиле ООП.


2) Не уверен, что правильно понял ваш вопрос, но предположу, что после:


trait Foo {
    fn foo(&self);
}

trait FooBar: Foo {
    fn foobar(&self);
}

Вы ожидаете, что в FooBar появится метод foo. Это не так, потому что требование реализации : Foo относится к тому типу, который будет реализовывать FooBar, а не к самому типажу FooBar. Строго говоря, вы не можете наследовать методы между типажами. Да и зачем это нужно? Необходимости в этом у меня не возникало.


3) Но часто ли вам действительно нужны такого рода иерархии? Причем самописные? Да, в их реализации есть определенные сложности (писал о них здесь), но в большинстве случаев я обхожусь использованием алгебраического типа данных.


Самое главное, наверное, это сразу освоить обобщенное программирование и научиться думать в терминах статических типов и их отдельных характеристик (типажей). И отойти от привычки смешивать наследование данных с образованием подтипа. К сожалению, пока нет хороших учебных материалов для этого, но ковыряние исходников популярных библиотек здорово помогает :)

ООП как такового в Rust нет (об этом упоминается в статье). Rust использует параметрический полиморфизм, а вместо наследования данных предлагается использовать аггрегацию. В таком случае смешивать наследование и полиморфизм подтипов, как зачастую происходит в ООП, не получится.
80% статьи я написал за один вечер. А оставшиеся 20% растянулись на два дня :)

Переходил на Rust с Java, полтора года назад. Понадобилось использовать C++, но после Java управление внешними зависимостями в C++ показалось настоящим кошмаром. А так, в разное время приходилось программировать на C/C++, Python, PHP, JavaScript и Java.


Переход был достаточно сложен: основная трудность состояла в том, чтобы переучиться и привыкнуть следовать правилам заимствования и владения. Тяжело было чисто психологически, а не технически (ошибки раздражали), ибо компилятор всегда выдавал исчерпывающие сообщения об ошибках и предложения по исправлению. Период "борьбы с компилятором" продолжался несколько месяцев (!), все время, пока я осваивал язык. Но после этого языком стало пользоваться весьма комфортно.


Синтаксис Rust'а поначалу казался вырвиглазным, но, как ни странно, к нему довольно быстро привык и трудности в чтении чужого кода не испытываю.


В целом — я доволен Rust'ом и пытаюсь его больше использовать в своих проектах, причем в основном для прикладных целей. К сожалению, не всегда это возможно: из-за молодости языка заказчики бывают против его использования. Еще минус — некоторая сырость языка и экосистемы вокруг него все еще присутствует. С каждым новым релизом (раз в 6 недель) она постепенно преодолевается, и сейчас состояние намного лучше, чем было год назад.

У точки с запятой, однако, есть и свои синтаксические преимущества. Так что в Rust это не просто бесполезный рудимент.

fn main() {
    for a in [1, 2, 3].iter().map(|x| x + 2).rev() {
        println!("{}", a);
    }
}

Заметьте, и это — в статически типизированном языке (:

С развитием Wasm такой универсальной средой для приложений станет веб-браузер. Я думаю «браузерные ОС» как раз хорошо подойдут в качестве решения для мобильников. Но для этого код должен работать быстро и нужен безопасный доступ к ресурсам платформы за пределами браузера.
Пока еще не понятно, что именно станет мейнстримом в использовании Wasm. Я не думаю, что старые схемы использования веб-приложений не претерпят изменений.
А по вашему Wasm применим только для SaaS? Тогда извините, мы говорим о разном.
Так есть же кэши и локальные хранилища, разве это не решает проблему?
А разве со свободными операционными системами не та же история? Есть репозитории пакетов, поставщики, которым ты так или иначе доверяешь.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity