LINUX.ORG.RU

Rust 1.10

 ,


0

4

Анонсирована очередная версия языка программирования Rust 1.10, разрабатываемого Mozilla совместно с сообществом.

Улучшения компилятора:

  • Добавлен новый тип крейта cdylib, предназначенный для экспорта C API. Основные отличия от dylib:
    • отсутствие метаданных;
    • разрешено LTO;
    • все библиотеки должны быть статически слинкованы;
    • экспортируются лишь те символы, которые помечены как extern. Например:
      pub fn foo() {} // не экспортируется
      #[no_mangle] pub extern fn bar() {} // экспортируется
    Для сравнения: «hello world» cdylib занимает 7.2КБ, а dylib - 2.4МБ.
  • Добавлена поддержка платформ i586-unknown-linux-gnu, i686-unknown-linux-musl, и armv7-linux-androideabi;
  • Снижено потребление памяти на ~100МБ при проверке типов;
  • Ускорена проверка T: Sized на 15%;
  • Улучшена кодогенерация при #[derive(Copy, Clone)].

Изменения в стандартной библиотеке:

Breaking changes!

  • AtomicBool теперь преобразуется в bool, а не isize. Демонстрация:
    use std::sync::atomic::AtomicBool;
    use std::mem::transmute;
    
    fn main() {
        let foo: bool = unsafe { transmute(AtomicBool::new(true)) };
    }
    
    На старых версиях компилятора будет ошибка;
  • time::Duration::new теперь будет паниковать при переполнении;
  • String::truncate теперь будет паниковать чуть меньше;
  • Небольшое изменение поведения макросов на этапе их парсинга: из :ty и :path следует :block;
  • Исправлен баг, связанный с гигиеной макросов. Следующий код будет валидным в устаревших версиях компилятора:
    fn main() {
        let x = true;
        macro_rules! foo { () => {
            let x = 0;
            macro_rules! bar { () => {x} }
            let _: bool = bar!();
            //^ `bar!()` использует первый `x` (который bool),
            //| а должен использовать второй `x` (который i32).
        }}
        foo! {};
    }
  • Переименование платформ:
    • arm-unknown-linux-gnueabi => arm-unknown-linux-gnu;
    • arm-unknown-linux-gnueabihf => arm-unknown-linux-gnu;
    • armv7-unknown-linux-gnueabihf => armv7-unknown-linux-gnu.
    Другими словами, изменены target_env, применяемые в conditional compilation.

Изменения в менеджере зависимостей Cargo:

  • Добавлен флаг --force, -f для подкоманды cargo install, предназначенной для загрузки исходных текстов из crates.io, их компиляции и установки в каталог ~/.cargo/bin. Это нововведение теперь позволит писать:
    cargo install FOO -f
    вместо:
    cargo uninstall FOO
    cargo install FOO
    Однако всё еще невозможно узнать, а требуется ли обновление вообще?
  • Диагностические сообщения теперь отправляются в stderr, а не в stdout;
  • С помощью флагов cargo doc --bin и cargo doc --lib можно выбрать: генерировать html документацию для проекта-приложения src/main.rs или проекта-библиотеки src/lib.rs;
  • В конфигурационном файле Cargo.toml, который можно встретить в корневом каталоге каждого проекта, теперь можно указать, каким образом макрос panic!() будет завершать приложение: unwind (по умолчанию) или abort;
  • Добавлен флаг cargo --explain FOO, поведение которого идентично rustc --explain FOO: показывает документацию по номеру ошибки;
  • В черный список имен крейтов добавлены ключевые слова раста, такие как fn, unsafe, let и прочее.

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



Проверено: tailgunner ()
Последнее исправление: cetjs2 (всего исправлений: 6)

Ответ на: комментарий от Esper

И в идеологии. И в уровне языка. И в возможностях.

Т.е. это именно идеология заставляет писать так:

Some(Pattern::Color(ColorPattern::new(color::new(color.red, color.green, color.blue, color.alpha))))

? (код из Servo, если что)

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

тут match (вместо того как в Swift сделали)

Можешь раскрыть мысль? Насколько я знаю, в свифте тоже паттерн матчинг есть, хоть и называется switch.

там нет перегрузки функций и даже с new надо писать:

Конкретно в этом примере, перегрузка и не нужна - достаточно дефолтных аргументов. Без них местами неприятно, согласен.

А с unwrap-то что не так?

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

Можешь раскрыть мысль? Насколько я знаю, в свифте тоже паттерн матчинг есть, хоть и называется switch.

Есть, а еще там можно писать так:

if let johnsStreet = john.residence?.address?.street {
    print("John's street name is \(johnsStreet).")
} else {
    print("Unable to retrieve the address.")
}

А на Rust будет портянка. Ну или может я ошибаюсь и кто-то покажет как можно просто записать.

Конкретно в этом примере, перегрузка и не нужна - достаточно дефолтных аргументов. Без них местами неприятно, согласен.

Нет, конкретно тут - нужна.

А с unwrap-то что не так?

Аналогично - не хватает сахара как в Swift.

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

Значит дело не только в опыте, но и в умении сделать язык удобным.

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

Вон даже в твоём примере с цветом: да, многословно, зато отлично видно из чего объект состоит. Если с кодовой базой не знаком, то разобраться будет несложно. Тут даже знание языка особо не нужно, чтобы примерно смысл понять.

Но сразу скажу: не уверен, что такая «читаемость» стоит того, чтобы «бороться за неё до конца» и мне самому кажется, что в расте с этим иногда перегибают. Хотя он мне всё равно больше свифта нравится.

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

Судя по твоему сообщению, ты просто ненавидишь C++. Похоже пару раз пытался что-то написать, наговнокодил, не понравилось и пошел говнокодить в расте. Говнокодить можно где-угодно.

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

Судя по твоему сообщению, ты просто ненавидишь C++.

А судя по твоему, телепат из тебя очень так себе. Даже в этой теме я говорил, что отвращения к С++ не испытываю: это мой основной рабочий инструмент.

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

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

Вот именно, что не кучу. При этом, да, «код, зачастую, действительно выглядит красивее и короче». И это не только равнозначно с «читается лучше», но и c «пишется проще».

Вон даже в твоём примере с цветом: да, многословно, зато отлично видно из чего объект состоит.

А ты точно сам не троллишь? Или, как tailgunner, просто сам Rust не используешь, а только пиаришь? Я не представляю, чтоб человек, вынужденный писать такой код регулярно, его одобрял.

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

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

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

А на Rust будет портянка

Ну да, тут будет многословнее и string interpolation тоже нет.

Нет, конкретно тут - нужна.

Зачем? Может я пример не понял, раскрой мысль что ли.

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

Зачем? Может я пример не понял, раскрой мысль что ли.

color::new(s.color.red, s.color.green, s.color.blue, s.color.alpha)

Какие дефолтные аргументы и как тут помогут?

// wota, которому порвало днище (с) обиженный за что-то tailguuner

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

Вот именно, что не кучу.

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

И это не только равнозначно с «читается лучше», но и c «пишется проще».

После изучения всех вариантов - да, пишется проще. Но ты-то про «читается» говорил, а теперь на пишется перескочил.

Повторюсь: я не считаю сахар и краткость бесполезными. Вот только читал срачи про скалу? Когда люди ноют, что написали «как проще», а остальные потом в нагромождении спец-символов разобраться не могут. Да чего скалу брать - даже про С++ можно найти нытьё мол фиг разберёшь, что происходит и как это найти. И это всего-лишь из-за возможности переопределять ограниченный набор операторов, виртуальных функций и тупых макросов. В общем, так далеко зайти можно. Мне самому интересно даст ли положительные плоды стремление раста к «очевидности».

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

Какие дефолтные аргументы и как тут помогут?

До сих пор не понял, если честно. Изначально подумал (и похоже зря), что претензия к невозможности сделать опциональные параметры (например, alpha).

Хорошо, что не так с кодом? Поостерегусь угадывать дальше.

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

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

Тогда уж «кучка».

Но ты-то про «читается» говорил, а теперь на пишется перескочил.

Нет, тема про «читается» осталась открытой.

Мне самому интересно даст ли положительные плоды стремление раста к «очевидности»

А поголовные макросы и возможность писать плагины для компилятора - это стремление к очевидности или нет?

// wota, которому выбило днище (с) обиженный tailgunner

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

Изначально подумал (и похоже зря), что претензия к невозможности сделать опциональные параметры (например, alpha).

Если ты внимательно посмотришь на код - это создание копии. В С++ тут просто было бы два конструктора - конструктор-копирования и тот, что в коде на Rust, причем, да, с опциональной alpha, например. Тут же тупо пишут копипасту (и это потенциально кривой код, который может при добавлении дополнительных полей, например, вызвать потерю данных, в отличие от конструктора-копирования, который правится один раз). А еще в С++ скорее всего вообще не пришлось бы руками создавать копию, но т.к. это тоже «неочевидное поведение», то не стану предъявлять за это претензии к Rust.

// wota, которому выбило днище (с) обиженный tailgunner

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

В С++ тут просто было бы два конструктора

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

// wota, которому выбило днище (с) обиженный tailgunner

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

std::marker::Copy

И это тоже, если точно известно описание типа.

Ты сперва разберись в вопросе, а потом начинай критиковать.

Согласен.

// wota, которому выбило днище (с) обиженный tailgunner

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

(прочитал тот пост ещё раз) Честно говоря, я не совсем понял, о чём ты.

То я протупил, увидел копипасту и сделал глупый вывод, а когда подумал, что копипаста может быть просто копипастой - уже не мог удалить пост.

// wota, которому выбило днище (с) обиженный tailgunner

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

Если во всяких С++ ... можно начинать говнокодить копипастом,

Ага, до первого запуска с segfault.

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

А поголовные макросы

Прямо уж поголовные? Опять же, ты всегда будешь видеть, что это именно макрос.

и возможность писать плагины для компилятора

Ага, но по прежнему без возможности изменить синтаксис до неузнаваемости.

Так, что да, стремление к очевидности.

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

Если ты внимательно посмотришь на код - это создание копии.

Теперь дошло. Ну да, трейт Clone или Copy был бы уместнее.

А еще в С++ скорее всего вообще не пришлось бы руками создавать копию

Зато пришлось бы руками указывать, что надо переместить. Ага, не везде, но всё-таки. Разные умолчания.

DarkEld3r ★★★★★
()

Ну что ж, я таки начал свой первый проект на Rust в виде клиента для сиплюсного кода. Вопрос - как сделать подготовительный шаг для тестов? Есть пачка тестов, которые дергают библиотеку на С++, библиотека на старте требует вызова функции инициализации. Сейчас этот вызов торчит в каждом тесте, что не особо нравится, куда этот вызов корректней всего воткнуть?

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

Но есть lazy-static и stainless (последний требует nightly).

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

anonymous
()

Breaking changes

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

Этот цирк кто-то действительно считает нормальным?

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

Меня одолело слепое хейтерство.

Посмотрел внимательней что поменяли, поглядел на изменения и прошлых 3-4х версий - по этой претензии сказать нечего.

Сел в лужу. Пока посижу, остыну.

anonymous
()

И где все эти умники, которые верещали как курица «вай-вай, D такой нестабильный, всё меняется!» - вот вам «Ржа» - продукт _коммерческой_ компании и такой же нестабильный - и ничё, никто не ноет.

Это к тому, что двуличные (или просто бестолковые) выкрики «Ди нестабилен» пора направлять в анус. Ди как раз намного стабильнее ржавчины - давно уже не делает серьёзных поломок.

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

«Ржа» - продукт _коммерческой_ компании и такой же нестабильный - и ничё, никто не ноет

Как это никто.

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

а в твоем

Во-первых он не мой.

все, что могут - это подключать сишные библиотеки.

Во-вторых это наглое ЛПП.
Зайди на crates.io

В-третьих FFI который в Ржавчине это охрененный плюс.
Я в своё время намучался с JNI

Ну а в-четвёртых, ты жирный троль.

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

Ди как раз намного стабильнее ржавчины - давно уже не делает серьёзных поломок.
matumba

Да пофиг уже всем. Еuо защитали «невзлетевшим» и похоронили. Кроме тупых виндо-обезьянок на него уже никто не фапает :)

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

Ди как раз намного стабильнее ржавчины - давно уже не делает серьёзных поломок.

Как же приятно звучит «Breaking changes!», но давай разберем поломки раста:

  • Функция transmute - это UB в чистом виде, ломать можно.
  • Конструктор у Duration принимает u64 секунд и u32 миллисекунд. Прошу заметить, что Duration способен хранить разницу во времени в размере 5849424173 веков, а паника произойдет за 50 суток до переполнения. Велика потеря? Нет. Но всё же пусть лучше упадет, нежели счетчик сбросится до нуля.
  • String::truncate будет меньше паниковать. Да, это breaking change, но панику то не убрали.
  • Немного изменили парсинг макросов, убрав неопределенность, которая может возникнуть в будущем при расширении синтаксиса языка.
  • Исправлен баг макросов, в D подобное пачками исправляют, судя по чейнджлогам.
  • Что же касается последнего пункта, то я допустил в новости ошибку, упомянул в комментариях, но ее так и не исправили. У каждой платформы есть некие характеристики: ОС, тип ОС, архитектура CPU, различные суффиксы/префиксы/расширения у имен файлов и прочее. Изменили лишь target_env, который теперь возвращает «gnu», «musl», либо «msvc». Я же посчитал, что уникальное имя платформы формируется конкатенацией соответствующих характеристик.
shaiZaigh
() автор топика
Ответ на: комментарий от anonymous

тут self надо всегда писать

Но ведь это прекрасно, так как даёт четкое разделение локальных переменных и данных структуры. В плюсах из-за этого придумали всякие m_* и прочее. Так что разница не большая.

там unwrap

Вы вообще понимаете зачем он там?

тут match

Наезд из разряда: «зачем мне писать if для указания условия».

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

Swift != Rust, и никогда им не будет. У них разные ниши. А простота синтаксиса объясняется полуавтоматическим управлением памяти, что плохо для системщины, но упрощает синтаксис.

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

Но ведь это прекрасно, так как даёт четкое разделение локальных переменных и данных структуры. В плюсах из-за этого придумали всякие m_* и прочее. Так что разница не большая.

В плюсах для этого есть this, если кто хочет. Ну и в плюсах не нужно писать this первым параметром для методов.

Вы вообще понимаете зачем он там?
Наезд из разряда: «зачем мне писать if для указания условия».

Возьмем уже приведенный пример:

if let johnsStreet = john.residence?.address?.street {
    print("John's street name is \(johnsStreet).")
} else {
    print("Unable to retrieve the address.")
}

Покажите как запишите на Rust. Учитывая, что я сам стал его использовать - это просьба не для меряния или критики.

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

Т.е. это именно идеология заставляет писать так:

1) Вкусовщина. 2) Раст придерживается идеологии явного описания (explicit), в том время, как тот же C++ позволяет использовать неявные приведение (implicit) и прочее, что, зачастую, приводит к большим проблемам.

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

Swift != Rust, и никогда им не будет. У них разные ниши.

Это не значит, что на них не решаются одинаковые задачи. Да и разница не так велика, как может показаться с первого взгляда.

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

Расширяйте свой кругозор.

А это уже фанатизм. Rust позволяет писать проще (об этом написано дальше), а ты защищаешь любой вариант, лишь бы на Rust.

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

В плюсах для этого есть this, если кто хочет. Ну и в плюсах не нужно писать this первым параметром для методов.

И это плохо. Зайдите на форумы новичков C++ - там половина ошибок - это перекрытие переменных класса локальными переменными. А если эта переменная еще и указатель, то получаем не инициализированный указатель в классе и UB. И раз на этом спотыкается почти 100% новичков, то это, всё же, проблема языка. И раст решает эту проблему.

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

Покажите как запишите на Rust.

Сейчас - по уродски или через try!. Но вы не переживайте - оператор ? уже в RFC и скоро будет в языке.

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