LINUX.ORG.RU

Rust 1.26

 


5

11

Команда разработчиков языка Rust рада представить новую версию Rust 1.26.0. Rust — системный язык программирования, ориентированный на безопасность, скорость и параллельность.

Обновить Rust можно с помощью команды:

curl https://sh.rustup.rs -sSf | sh # если у вас еще не установлен rustup
rustup update stable

Основные изменения:

  • Вторая редакция книги «The Rust Programming Language» (почти) готова, и теперь рекомендована по умолчанию для ознакомления вместо первой версии. Также готовится к выходу бумажное издание книги.
  • impl Trait в заголовках функций

    Стало возможно указывать Trait в заголовке функции в качестве типа возвращаемого значения:

    fn foo() -> impl Iterator<Item = i32> {
        // ...
    }
    
    Это позволяет не указывать полный тип в заголовке функции, если с точки зрения API конкретный тип не имеет значения. Такой синтаксис подразумевает статическую диспетчеризацию, в отличие от Box<Trait>.

    Также эта возможность удобна для использования с замыканиями (closures):

    fn foo() -> impl Fn(i32) -> i32 {
        |x| x + 1
    }
    

    Новый синтаксис теперь можно использовать и для типов аргументов фунции:

    // раньше нужно было писать так:
    fn foo<T: Trait>(x: T) {
    
    // сейчас можно так:
    fn foo(x: impl Trait) {
    

  • Неявное разыменование ссылок в сопоставлении с образцом (match, if let, ...)

    Теперь следующий код больше не вызывает ошибку компиляции:

    fn hello(arg: &Option<String>) {
        match arg {
            Some(name) => println!("Hello {}!", name),
            None => println!("I don't know who you are."),
        }
    }
    
    и эквивалентен такому:
    fn hello(arg: &Option<String>) {
        match arg {
            &Some(ref name) => println!("Hello {}!", name),
            &None => println!("I don't know who you are."),
        }
    }
    
    То же работает и для &mut + ref mut.

  • Раскрытие срезов (slice) в сопоставлении с образцом
    fn foo(s: &[u8]) {
        match s {
            [a, b] => (),
            [1, _, _] => (),
            _ => (),
        }
    }
    
  • Закрытые интервалы вида 0..=4, включающие обе границы в диапазон перечисления
        for i in 0..=4 {
            println!("i: {}", i); // выведет 0, 1, 2, 3 и 4
        }
    
  • Новые целочисленные типы i128 и u128
  • Функция main() теперь может возвращать тип Result
    use std::fs::File;
    
    fn main() -> Result<(), std::io::Error> {
        let f = File::open("bar.txt")?;
    
        Ok(())
    }
    
  • Ускорения в работе компилятора
  • Стабилизирована функция std::fs::read_to_string
  • При форматировании через trait Debug теперь можно выводить целочисленные значения в шестнадцатеричном виде:
    assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]")
    
  • Номер версии Cargo, начиная с этого релиза, изменяется синхронно с номером версии Rust

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

★★★★★

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

Ответ на: комментарий от shkolnick-kun

Ну не на питоне же имбед писать? Как насчет Go?

Шаришся в поисках съестного по закоулкам гитхаба? 😁

Для системного программирования либо чистый Си либо Раст. Go не катит.

Кстати, посмотрел лицензию «BSD 3-Кляуз „New“ or „Revised“ License». Чёрт! Хотел увидеть лютый GNU v3. Нее пацаны бзда не катит.

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

Да, и он выведен компилятором.

Если он выведен, почему ж компилятор ругается на стандартные для типа операции?

Анонимные типы - тоже (ах да, анонимизированные, anonymized).

Видишь, ты вертишься как уж, вот сейчас написал про «вывод анонимизированного типа» и хрен поймёшь, что ты там имел в виду, то ли что выведен реальный тип (что неправда), то ли что выведен плейсхолдер (тип_возврата_функции_foo_про_который_известно_что_он_реализует_Debug, что правда). А всё почему? Потому что ты облажался и собираешься тянуть резину.

А что релевантно? Что ты хочешь знать - настоящий тип значения анонимизированного типа? Серьезно?

Внезапно: для программиста важно чтоб программа скомпилялась и работала правильно. Конкретная реализация компилятора может на этапе проверки типов знать реальный тип переменной и ругаться для проформы или знать только часть информации об этом типе, для кодера на расте это вообще неважно.

Ну и напомню контекст. Ты ворвался сюда, обозвал меня наркоманом и заявил, что я фигню написал, что у кода, работающего с анонимизированным типом нет ничего общего с кодом, работающим с типом-параметром дженерика и что реальный тип выводится. Я привел пример программы с 2мя переменными, реальный тип обеих i32, тип обеих выводится, и продемонстрировал, что компилятор знает об одной больше чем о другой. Ты пообещал доказать, что тип выводится одинаково, но слился пытаясь втюхать MIR. Мне пофиг, я готов поверить, что ты прочитал невнимательно вопрос, что ты забыл контекст и так далее, но вопрос выводимости реального типа был вспомогательным, главная твоя претензия в подобии дженерику. В общем, если хочешь, давай вернёмся к сравнению.

Итак:

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

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

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

Да, и он выведен компилятором.

Если он выведен

Никаких «если» - он выведен, это видно из MIR.

почему ж компилятор ругается на стандартные для типа операции?

Потому семантика языка указывает, что на значении этого типа могут использоваться только операции указанного трейта.

[...]

Дальше не читал.

tailgunner ★★★★★
()

Неявное разыменование ссылок — это классно, но хотелось бы больше неявностей и наркоманского синтаксиса.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

А ты типо хотел сказать что то другое?
Я вот сейчас открыл рандомный файл в Mojolicious, и в Rocket.rs, Perl намного читабельнее, даже можно не спорить, это просто видно, лол.

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

Я одного не пойму: почему бы не обратиться к первоисточнику? Я накопал две ссылки: обсуждение оригинального RFC, но его долго читать, и запись в блоге Аарона Тюрона, где он мух с котлетами всё-таки не смешивает:

Like generics, unboxed abstract types guarantee static dispatch and inline data layout.

То есть бенефиты, как от генериков, но это всё же не генерики.

Разницу я уже описывал: unboxed abstract types описывают конечное множество (существующих) типов, которое составляют все точки выхода из функции, в отличие от генериков.

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

fn foo<X: T>() -> X says «for any type X implementing T, I'll produce an X».

fn foo() -> impl T says «there's some hidden type X implementing T; I'll produce an X»

You cannot use generic types/default type parameters to get at the second meaning, because the point is that the function's code produces a single, concrete return type of its choosing.

From the compiler's point of view, what the caller knows depends on the stage of the compiler:

  • during typechecking, the caller knows only the trait bound, not the concrete type
  • during codegen, the caller knows the concrete type and generates statically-dispatched calls, etc.
Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Клевый у вас срач о нюансах уберязычка, которые даже адепты не раскуривают. Воистину раст - убийца цепепе (на полях священных войн, не в реале же).

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

Мне кажется в твоем примере оно не может найти не тип b а тип результата сложения, так работает

fn get_my_trait() -> impl MyTrait + std::ops::Add<i32, Output = impl std::fmt::Display> {
    1
}

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

Посоны просто устали ждать на берегу реки, когда проплывет труп Раста. Поддерживают энтузиазм, как могут, поиском пятен на Солнце.

Virtuos86 ★★★★★
()
Ответ на: комментарий от shkolnick-kun

А у тебя не возникает вопроса, для чего нужен дешевый имбед?

Нет, конечно. Я знаю, зачем он нужен. Но я так же знаю, что мир имбеда не ограничивается дешевым имбедом, так что найдется имбед и на Питоне, и на JS.

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

Да пойнт был не в том, чтобы написать компилируемый код, а в том, чтобы показать, как компилятор воспринимает описание impl Trait на выходе функции.

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

Никаких «если» - он выведен, это видно из MIR.

Как я уже писал, ни MIR, ни даже скриншот из отладчика, подтверждающий, что в какой-то момент реальный тип значения известен компилятору меня не интересуют. Это, внимание, детали реализации конкретного компилятора. Важно что по этому поводу требует язык. Надеюсь, хотя бы со второго раза до тебя дойдет и больше я этот бред про MIR тут не увижу.

Потому семантика языка указывает, что на значении этого типа могут использоваться только операции указанного трейта.

Ну давай продолжай свою мысль. Какого типа значения позволяют только операции указанного трейта? u32 из твоего примера? Или всё-таки механизм вывода типов языка Раст вывел какой-то другой тип, не u32?

То то же. Язык Раст требует от совместимого компилятора, даже если тому уже известно, что реальный тип переменной i32, симулировать незнание и ругаться на операцию, не определённую для указанного трейта. Теперь дошло?

Дальше не читал.

Но если бы прочитал, обязательно бы ответил что-то убойное. Жаль что не прочитал. Слив засчитан.

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

Слив засчитан.

Ну слава ТНБ, а то я думал, это никогда не кончится.

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

Что-то кроме вот этого [https://zeppelinos.org/] кефирного эрзаца ничего не ищется, остальное - обертки над Си.

zeppelinos че-то совсем не похожа на операционную систему — судя по первой странице сайта это какая-то надстройка на эфиром (ethereum)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

You cannot use generic types/default type parameters to get at the second meaning, because the point is that the function's code produces a single, concrete return type of its choosing.

очень интересно, если так; я-то надеялся, что функция в расте может возвращать неизвестный тип

а дальше? и в коллекцию (массив, вектор, очередь,...) неизвестный тип (или указатель на него) тоже не положить? (т.е. тип, у которого известен только impl Trait, и этот impl Trait один и тот же на всю коллекцию)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от anonymous

Открываем для себя Box<Trait>.

а оттуда можно вытащить реальный тип значения после анбокса?

речь идет о существовании такого бокса, который не знает ничего, кроме Trait, и не скажет реального типа даже под пытками (ну там unsafe)

з.ы. если возникает вопрос «как так может быть без нарушения type safety» — так может быть, но возможно не в расте

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 4)
Ответ на: комментарий от linuhs_user

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

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от anonymous

в расте с токио это вернет future, которую можно использовать дальше в своем асинхронном сервере

В этом вся соль Го. Футуры в расте выглядят как калечные аномалии, как песчинка в глазу. Го как-раз и был создан, чтобы унять эту конкретную боль

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

Синтаксисом

Специальным синтаксисом для чтения-записи?

и умением в n:m

И что, это нужно на практике? Вот именно N:M.

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

Для крайних случаев есть mem::transmute. Это аналог reinterpret_cast из С++.

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

Box<Any<Trait>> и даункастишь к нужному типу, если там именно он.

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

Можно, enum тоже приводит все входящие в него типы к одному размеру (максимальному).

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

очень интересно, если так; я-то надеялся, что функция в расте может возвращать неизвестный тип

Но как? Чтобы вернуть что-то из функции, нужно это что-то создать в функции, а вывод типов потребует точно указать тип этого объекта. Запихать в функцию что угодно можно, если она обобщенная, вернуть же получится только конкретный тип.

а дальше? и в коллекцию (массив, вектор, очередь,...) неизвестный тип (или указатель на него) тоже не положить?

Пока что impl Trait разрешен только в сигнатуре функций, поэтому коллекцию именно неизвестных типов точно создать не выйдет, потому что все коллекции типизированные. Опять же коллекции, как минимум, векторы и массивы, требуют, чтобы их элементы были Sized, т.е. имели размер, известный на этапе компиляции, а какие типажи соответствуют этому условию?

А коллекцию указателей создать всегда можно было, Box наше всё.

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

Да, вчера генассамблея ООН приняла. Теперь будешь топить за Раст уже? Удивительная закономерность, чем человек дурнее, тем больше в нем почтения к бумажками, принятым очередным комитетом международных балаболов.

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

Ну не стандарт, спецификации какая-то. Что такое «язык Раст», диктующий какой-то бред своим реализациям? Кстати, много реализаций то уже наклепали?

//bread

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

почтения к бумажками, принятым очередным комитетом международных балаболов

Студня бывалого с лабами мощными вижу я в этом регистранте.

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

более-менее живывые проекты требуют последнюю версию компилятора

А почему это проблема собсна? Если, конечно, не nightly

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

более-менее живывые проекты требуют последнюю версию компилятора

А почему это проблема собсна?

Потому что сборка требует обновления компилятора. Отнюдь не везде тебе это позволят, и отнюдь не везде, где это позволили бы, позволят сделать это методом curl | sh.

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

Насколько я понимаю, спецификации нет, вместо неё дока и рфцшки. Но это не точно.

Альтернативные реализации компилятора, как ни странно, есть.

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

Студня бывалого с

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

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

мы же про safety говорим, не про security?

Про нее родимую.

Безопасность гарантируемая языком это важно, кто бы спорил, но есть задачи где она занимает не самое первое место

К формулировке можно придраться, согласен. Я имел в виду, что та же безопасность (в смысле safety) что и в Расте достигается сборщиком мусора. Т.е. нет смысла убиваться так как в Расте, а можно просто спокойно решать задачу. Глубоко сомневаюсь, даже нет, уверен, что Расту никогда (вот так вот прямо категорично - никогда) не сравниться с Питоном в области анализа данных и прочего машинного обучения. Просто потому что все эти статистики посмотрят и скажут - вы че, еб..сь? Как я на этом буду писать?

Раст отличный инструмент для решения своих задач, но он нишевый. Как и остальные, в принципе.

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

Да? Ну окей, не стану спорить. Вполне возможно, что ты знаешь и Rust, и Си++ лучше, чем я.

И правильно, спорить не о чем. Из плюсов сделать раст невозможно. Что это за бред? Давайте из плюсов сделаем еще питон, джаву и прочее? Тут даже не надо знать ни раст, ни плюсы, чтобы понять, что у них у каждого свой бекграунд, свои цели и свое будущее.

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

А почему стандарт не запилят?

Как минимум потому, что язык довольно быстро меняется (совместимо снизу вверх, но всё же). И непонятно, интересно ли это Мозилле (в конце концов, Perl, Python, Go, Swift не стандартизированы, но живут неплохо).

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от khrundel

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

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

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