LINUX.ORG.RU

Rust 0.12

 ,


5

9

Вышла новая версия инструментов разработки языка программирования Rust. Rust — язык системного программирования, предназначенный для написания быстрых и в то же время безопасных (в том числе и во многопоточной среде) приложений.

В данном релизе упор был сделан на переработку документации языка, приведение к единому виду стандартной библиотеки, улучшение пакетного менеджера Cargo и поддержки Windows.

Обзор обновлений в новой версии:

  • Около 1900 изменений в коде.
  • Основные изменения
    • Вводный документ (и набор сопроводительной документации) был полностью переписан и теперь называется The Rust Guide.
    • Множественные улучшения пакетного менеджера Cargo и его поддержка большим числом библиотек.
    • Большое количество изменений API в стандартной библиотеке std для соответствия текущим стандартам разработки Rust. Все изменения отражены в документации.
    • Ряд библиотек был вынесен из дерева Rust во внешние проекты на Github: uuid, semver, glob, num, hexfloat, fourcc. Они могут быть установлены с помощью Cargo.
    • Новая возможность: lifetime elision - позволяет во многих случаях не указывать явно аннотацию времени жизни (lifetime) в сигнатурах методов.
    • Появилась версия компилятора для Windows 64-bit.
  • Язык
    • Операцию индексации теперь можно перегрузить в своих типах данных с помощью трейтов (trait) Index и IndexMut.
    • Конструкция if let теперь выполняется только при совпадении let-паттерна.
    • Новый синтаксис для срезов (slices), например: [0..4]. Поддержать подобный синтаксис в своих типах данных можно с помощью трейтов Slice и SliceMut.
    • Синтаксис для сравнения с образцом срезов стал постфиксным, теперь он имеет вид: [a, b, c..].
    • При использовании интервалов с включением в сравнении с образцом теперь верхняя границы считается не включенной: вместо 0..3 стоит указывать 0...4.
    • Элементы кортежей и кортежных структур теперь могут быть получены с помощью нового синтаксиса индексации: value.0.
    • Атрибут #[crate_id] теперь не поддерживается, версионирование выполняется исключительно пакетным менеджером.
    • Импорт библиотек с переименованием теперь записывается как extern crate foo as bar вместо extern crate bar = foo.
    • Оператор use с переименованием теперь имеет новый синтаксис: use foo as bar вместо use bar = foo.
    • Добавлен новый, более эффективный тип замыканий: unboxed closures. Со временем текущий тип замыканий будет заменен новым.
    • Добавлено ключевое слово move, которое описывает замыкания, захватывающие переменные по значению.
    • Модификация (mutation) и присваивание теперь не могут использоваться в pattern guards.
    • Параметризованные структуры и перечисления теперь могут быть ограничены (иметь trait bounds).
    • Новый, более гибкий синтаксис указания ограничений типов с помощью ключевого слова where
    • Трейт Share переименован в Sync для того, чтобы термин shared обозначал только shared reference.
    • Для типов динамического размера добавлен трейт Sized. Чтобы указать, что параметр типа не должен иметь строгий размер, стоит использовать ограничение: <Sized? T>.
    • Замыкания теперь могут возвращать !, примеры сигнатур: || -> !, proc() -> !.
    • Границы времени жизни (lifetime bounds) теперь могут быть применены к параметрам типа и типам объектов.
    • Старый тип автоматически автоматически управляемых ссылок со сборкой мусора GC<T> окончательно был удален. В будущем появится новая реализация управления памятью со сборкой мусора.
  • Библиотеки
    • Улучшена документация к ряду библиотек.
    • Обновлены битовые векторы: collections::bitv.
    • Библиотека url признана устаревшей. Рекомендуется использовать http://github.com/servo/rust-url, устанавливаемую с помощью Cargo.
    • Почти все типы данных потоков (stream) ввода-вывода теперь могут быть клонированы и закрыты в других потоках (thread) выполнения.
    • Добавлен тип std::time::Duration для использования в методах ввода-вывода, зависящих от таймера.
    • The runtime I/O abstraction layer that enabled the green thread scheduler to do non-thread-blocking I/O has been removed, along with the libuv-based implementation employed by the green thread scheduler. This will greatly simplify the future I/O work.
    • collections::btree переписана с учетом более эффективного и близкого к Rust проектирования.
  • Утилиты
    • Вывод rustdoc теперь содержит метку об уровне стабильности API.
    • Флаг --crate-name теперь может указывать имя компилируемой единицы кода (crate), что ранее указывалось в коде атрибутом #[crate_name.
    • Флаг -C metadata указывает дополнительные метаданные, хэш которых должен попасть в символьные имена собираемого бинарника.
    • Флаг -C extra-filename указывает дополнительную информацию, добавляемую в имя выходного файла для использования пакетным менеджером.
    • Улучшена генерация отладочной информации, которая теперь лучше совместима при отладке через gdb и lldb.
    • Добавлена экспериментальная поддержка параллельной компиляции с помощью флага rustc -C codegen-units.
    • Компилятор теперь не добавляет по умолчанию в бинарные файлы путь для поиска библиотек (rpath).
  • Прочее
    • Оптимизировано использование стека с помощью аннотаций LLVM.
    • Rust для Linux более совместим со старыми версиями ядер и дистрибутивов.

>>> Подробности



Проверено: maxcom ()
Последнее исправление: CYB3R (всего исправлений: 3)
Ответ на: комментарий от anonymous

Тебе должен понравиться Cobol.

anonymous
()
Ответ на: комментарий от void_ptr

Ты про stacktrace не знаешь что-ли, петушок?

anonymous
()

Btw, а я правильно понимаю, что в язык и не собираются запиливать поддержку виртуальных функций и исключений? Вообще это даже скорее хорошо.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Исключения пытаются изобразить макросами, виртуальные функции обсуждаются в рамках предложений по ООП.

tailgunner ★★★★★
()
Ответ на: комментарий от Legioner

Хм, тут много раз вызывается малюсенькая процедура... А если #[no_stack_check] перед fib добавить?

#[no_stack_check]
fn fib(n: int) -> int {
    if n <= 1 { n } else { fib(n - 1) + fib(n - 2) }
}
fn main() {
    let n = 45i;
    println!("fib({}) = {}", n, fib(n));
}

Или #[no_split_stack], если компилятор «старый».

ozkriff
()
Ответ на: комментарий от mix_mix

... виртуальных функций ...

Эм, а куда их впиливать, если в языке нет наследования? И зачем они нужны, если трейты примерно то же самое могут?

ozkriff
()
Ответ на: комментарий от ozkriff

Нет, это лишь статик. Засунь ты указатели на фигуры в вектор и посчитай площадь в foreach, вот тогда это было бы динамик.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Нет, это лишь статик.

Эээм, почему? Статическая диспечеризация была бы в этом случае:

fn print_area_static<T: HasArea>(shape: T) {
    println!("This shape has an area of {}", shape.area());
}

Засунь ты указатели на фигуры в вектор и посчитай площадь в foreach, вот тогда это было бы динамик.

Ну ок, вот:

http://is.gd/t6RyaR

let v: Vec<&HasArea> = vec![&c as &HasArea, &s as &HasArea];
for &shape in v.iter() {
    print_area(shape);
}
ozkriff
()
Ответ на: комментарий от tailgunner

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

ozkriff
()
Ответ на: комментарий от ozkriff

Ну в случае первого примера оф. гайд говорит, что применяется статическая: When we use this trait with Circle and Square, Rust ends up generating two different functions with the concrete type [...] But as you can see, there's no overhead of deciding which version to call here, hence 'statically dispatched.' А за второй пример спасибо, не знал.

mix_mix ★★★★★
()
Ответ на: комментарий от tailgunner

Every trait item (see traits) defines a type with the same name as the trait. This type is called the object type of the trait. Object types permit «late binding» of methods, dispatched using virtual method tables («vtables»). Whereas most calls to trait methods are «early bound» (statically resolved) to specific implementations at compile time, a call to a method on an object type is only resolved to a vtable entry at compile time. The actual implementation for each vtable entry can vary on an object-by-object basis.

Ок, вопрос отпал.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Есть разница между:

fn print_area(shape: &HasArea) { /*не важно*/ }

и

fn print_area_static<T: HasArea>(shape: T) { /*не важно*/ }

В руководстве рассматривается второй вариант, а у меня по обоим ссылкам на play.rust-lang.org был первый.

ozkriff
()

посоны, дабы не плодить сущности - если вот просто для себя для расширения кругозора - что выбрать, ocaml или sml?

anonymous
()
Ответ на: комментарий от ozkriff

Второй вариант помог (0.12.0). Даже чуток перегнал clang, не знаю, как там с gcc дело будет. Вера в язык укрепилась, спасибо :)

Legioner ★★★★★
()
Ответ на: комментарий от ozkriff

В руководстве рассматривается второй вариант, а у меня по обоим ссылкам на play.rust-lang.org был первый.

Да, я не заметил, ты прав. Однако уже при -O2 на деле всё же применяется статическая (заодно и инлайнится всё, что можно). Круто, что сказать.

mix_mix ★★★★★
()
Ответ на: комментарий от WatchCat

Потому что мне писать программы и я не хочу продираться через тучи скобок.

Ты же в курсе, что в сишном синтаксисе скобок не сильно меньше, просто они не так расположены, да?

А уменя уже сложилось плохое отношение к лисперам которые тянут любимый синтаксис куда только можно, что есть предел упоротости и суть лисперовских фанбоев.
Но не лезьте с проповедями о единственно правильном пути к другим людям.

Нифига себе, успокойся) Вроде никто к тебе не лез с «единственно правильном путем» в стиле уличных проповедников в этой теме. Ты у меня спросил, как я себе представляю запись выражения без инфиксных операторов - я тебе два варианта написал и аноним про лиспы сказал (пускай и не в самой вежливой форме, но мы же на лоре).

Я выразил своё отношение к лиспу и больше дискутировать на эту тему не хочу.

Ок, перестаю развивать эту тему.

А почему бы тогда не писать на брейнфаке?

Хм, главное тут, думаю, это отсутствие нормальных средств построения абстракций. Так-то он мне изувеченный Форт всегда напоминал - тоже конкатенативный, пускай и не стековый - а Форты - очень интересное семейство языков.

... APL ...

Про эту странную штуку (как и про J) я, боюсь, ничего сказать не смогу - я их не знаю и узнавать не хочу, слишком уж они узкоспециализированные и математичные (но финн и джейк бы одобрили, да).

ozkriff
()
Ответ на: комментарий от WatchCat

Да видел в чужом коде давно еще - https://github.com/search?l=rust&q=no_split_stack&type=Code , пару раз в irc мелькало - https://botbot.me/mozilla/rust/search/?q=no_split_stack и есть парочка задач на гитхабе, типа https://github.com/rust-lang/rust/issues/8345 .

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

upd: Вот еще эту ссылку нашел http://www.reddit.com/r/rust/comments/1t1s1k/this_week_in_rust_16_dec_2013/ce... . Выглядит более-менее актуально.

ozkriff
()
Последнее исправление: ozkriff (всего исправлений: 1)
Ответ на: Ненужно! от anonymous

Конечно же нет, толстяк, никому такое не нужно :) .

Но, кстати, с неделю назад произошли довольно интересные изменения с глобальными переменными: https://github.com/rust-lang/rfcs/blob/bacdc4129/text/0246-const-vs-static.md . Наконец-то нормально разделили глобальные переменные (с реальным адресом в памяти) и глобальные константы (которые просто значение):

This change is an implementation of RFC 69 (ха-ха) which adds a third kind of global to the language, const. This global is most similar to what the old static was, and if you're unsure about what to use then you should use a const.

The semantics of these three kinds of globals are:

* A const does not represent a memory location, but only a value. Constants are translated as rvalues, which means that their values are directly inlined at usage location (similar to a #define in C/C++). Constant values are, well, constant, and can not be modified. Any «modification» is actually a modification to a local value on the stack rather than the actual constant itself.

Almost all values are allowed inside constants, whether they have interior mutability or not. There are a few minor restrictions listed in the RFC, but they should in general not come up too often.

* A static now always represents a memory location (unconditionally). Any references to the same static are actually a reference to the same memory location. Only values whose types ascribe to Sync are allowed in a static. This restriction is in place because many threads may access a static concurrently. Lifting this restriction (and allowing unsafe access) is a future extension not implemented at this time.

* A static mut continues to always represent a memory location. All references to a static mut continue to be unsafe.

ozkriff
()
Ответ на: комментарий от ozkriff

все-таки в ржавчине поощряется явная проверка ошибок

Насчёт длины спорить не буду, хотя как минимум в некоторых места, по моему, раст должен выигрывать (речь про сложные шаблоны). Но сам аргумент мне кажется странным. Если а плюсах забивают на обработку ошибок, то код (в большинстве случаев) будет работать неправильно (ну или «плохо»). А зачем сравнивать рабочий код с нерабочим?

DarkEld3r ★★★★★
()
Ответ на: комментарий от ozkriff

Думаешь, в этом языке что-то магическое, что привлекает особенно «увлеченных»?

А разве нет? Лисп часто позиционируют как «очень гибкий и не ограничивающий язык». А это ведь лестно для впечатлительных личностей. Мол - могу любые навороты делать, а не писать «бойлерплейт на джаве/плюсах». Другое дело, что они это использовать не будут.

Про профессионалов, которые действительно всё это используют ничего плохого не скажу.

Ну и подобная фигня не только лиспа касается. Точно так же, есть люди, которые «признают только С/С++» - типа на других языках они не смогут «выжать всю производительность» и виртуальные машины и сборка мусора тормозят. И аналогично, люди использующие такие аргументы, могут писать какую-нибудь фигню, где всё это и не нужно.

DarkEld3r ★★★★★
()
Ответ на: комментарий от ozkriff

На сколько помню после 0.12 должна идти 1.0, а тут 0.13. То есть до релиза ещё ~6 месяцев. Или я ошибаюсь?

anonymous
()
Ответ на: комментарий от anonymous

Я про 0.13 ничего не знаю, только многократно видел заявления, что планируют выпуск стабильной версии в начале 2015ого. Чего-то в духе «если все будет ок, то в начале 2015 выкатываем бету и вскоре, если в бете не найдется больших косяков, выпускаем стабильную версию».

ozkriff
()
Ответ на: комментарий от anonymous

Ну хорошо, только что оно «0.13.0-nightly» и знаю. Только это ничего не значит: может, около декабря и правда выпустят 0.13 версию, может, 0.13 не выпустят до января, а там ее переобзовут в 1.0 RC. Или еще что, я без малейшего понятия про судьбу 0.13)

А откуда ты про шесть месяцев взял?

ozkriff
()
Ответ на: комментарий от ozkriff

Выпуск одного релиза происходит за ~3 месяца => 3 месяца(0.13) + 3 месяца (1.0) = 6. Как-то так)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.