LINUX.ORG.RU

Rust 1.26

 


5

9

Команда разработчиков языка 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 ()

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

fn foo() -> impl Iterator<Item = i32> {
    // ...
}

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

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

Давайте вообще точки уберём и другую синтаксическую конструкцию завезём, чтобы точно ни один даун не мог перепутать. Предлагаю .. для полузамкнутого диапазона и to для замкнутого.

Softwayer ★★ ()

impl Trait в заголовках функций

Наконец-то что-то крупное стабилизировали. А то прямо какое-то затишье было.

Кстати, вроде же хотели ещё SIMD стабилизировать. Не успели к этому релизу?

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

Давайте вообще точки уберём и другую синтаксическую конструкцию завезём, чтобы точно ни один даун не мог перепутать

Зачем? Просто убрать конструкцию "...". Как бонус - баттхерт эстетов.

tailgunner ★★★★★ ()

Неявное разыменование ссылок в шаблонах подстановки

шаблонах подстановки

Это называется «сопоставление с образцом». Можно заменить на «в конструкциях сопоставления с образцом».

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

Ассемблер тот же: https://stackoverflow.com/a/34239917.

Раз есть нативные операции, в результате которых получается 128-разрядный int, значит и тип определённо нужен. Другие операции «эмулируются» несколькими инструкциями.

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

// сейчас можно так:
fn foo(x: impl Trait) {

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

0..=4 Чувствуется уже с описания Раст ждет такая же участь что и C++. Начнут капитально засирать язык и теперь будет неоднозначный синтаксис, где любую мелочь моно описать 10 разными способами.

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

Надо было изначально делать диапазоны включительно в оба конца. Теперь будет костыль в языке.

Потому что всегда проще на единицу меньше сделать диапазон, чем думать как побороть случай 0.255 для u8.

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

Надо было изначально делать диапазоны включительно в оба конца. Теперь будет костыль в языке.

Не надо было. Для тех, кто пришел с Си, Java, Python это непривычно, а о паскалистах никто не беспокоится.

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

Статический полиморфизм - это fn belochka<T: Trait>() -> T.

А fn bulochka() -> impl Trait переводится как «моя функция возрвращает некий конкретный тип, реализующий Trait, но мне влом его указывать, нехай компилятор сам догадается».

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

Это статический полиморфизм на дженериках и на трейтах. Динамического полиморфизма в расте нет. Компилятор знает заранее все. В этом прелесть языка. Можно реализовать в расте и динамику, но уже будет unsafe и будет ручками все.

baist ()