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)
Ответ на: комментарий от tailgunner

Ну да, неканонично написал. Но I там таки обозначало именно единицу, и по-русски говорили именно п-эль-один.

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

Суть в том, что в расте все вебсерверы по-прежнему на уровне альфы. А Go, в принципе заточен под эту задачу.

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

меня все это интересует только в качестве бэкенда

Если главный критерий оценки - производительность хелловорлда на siege, то у тебя есть явный победитель - Go. Используй его.

Чего к словам придираться

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

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

Неканонично и не в тему. Как бывший программист на PL/I могу сказать, что у Rust и PL/I ничего общего нет.

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

Я выражаюсь неряшливо, я Гитлер ЛОРа, прошу прощения.

Все что меня интересовало, можно ли повысить производительность того что я протестировал или нет, и меньше всего что меня инетресует это флейм.

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

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

Тогда начнутся проблемы со случаем, когда элементов для итерации нет. Если интервал от 0 до l, а l = 0, то 0..l это пусто. А если бы надо было писать 0..l-1, то для unsigned бы было переполнение, и пришлось писать if.

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

Все что меня интересовало, можно ли повысить производительность того что я протестировал или нет

Можно, конечно. Изучаешь сорцы hyper, профилируешь, переписываешь, PROFIT.

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

Жалко тут нет эмоций к каментам.

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

А потому однозначно GO.

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

А потому однозначно GO.

Не то что бы я «за раст», просто мимокрокодил, но таки твои аргументы совсем не вызывают уважения.

Разница между лучшими результатами (из приведённых тобою) - 17.5к vs 21к приблизительно 17%.

Вангую что в реальной нагрузке подобная разница будет статистически плохо различима ввиду сильно большего потребления времени реальной задачей, а не фреймворком. Ну т.е. «задача» котроая генерирует ответ будет минимум раз в 10 «тяжелее» чем пустая страница, значит разница сократиться примерно в те же 10 раз и будет составлять приблизительно 2%.

При этом вопрос стоимости разработки и сопровождения ты совершенно упускаешь из виду. Мягко говоря странно.

Почему тогда не взять си? на нём можно найти веб фреймворк, полагаю, и он наверняка «уделает» по «скорости» и раст и го.

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

А потому однозначно GO.

То, что для задачи «сервить хелловорлд» нужно выбирать Go, ясно было с самого начала, когда ты привел результаты siege.

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

При этом вопрос стоимости разработки и сопровождения ты совершенно упускаешь из виду. Мягко говоря странно.

Если брать во внимание этот вопрос, то тем-более нужно выбрать именно Go.

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

Крайне любопытно поглядеть ваши выкладки. А то ведь с тем же успехом можно сказать «Если брать во внимание этот вопрос, то тем-более нужно выбрать именно Си.»

AndreyKl ★★★★★
()
Ответ на: RUST мы GO как WEB framework от theromis

Запускал на одной машине.

hyper = "0.11.26"
num_cpus = "1.8.0"
extern crate hyper;
extern crate num_cpus;

use hyper::server::{const_service, service_fn, Http, Response};

const TEXT: &str = "Hello, World!";

fn main() -> Result<(), hyper::Error> {
    let addr = ([127, 0, 0, 1], 3000).into();

    let hello = const_service(service_fn(
        |_req| Ok(Response::<hyper::Body>::new().with_body(TEXT)),
    ));

    let server = Http::new().bind(&addr, hello)?;
    server.run_threads(num_cpus::get());
    Ok(())
}
$ wrk -c 100 -t 4 http://127.0.0.1:3000
Running 10s test @ http://127.0.0.1:3000
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.13ms   43.24ms   4.28s    99.70%
    Req/Sec    31.99k     5.15k   51.33k    62.87%
  1201909 requests in 10.00s, 122.65MB read
  Socket errors: connect 0, read 0, write 0, timeout 67
Requests/sec: 120197.87
Transfer/sec:     12.27MB
package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":3001", nil))
}
$ wrk -c 100 -t 4 http://127.0.0.1:3001
Running 10s test @ http://127.0.0.1:3001
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.50ms    5.09ms 157.58ms   97.96%
    Req/Sec    21.53k     7.78k   81.56k    70.84%
  811817 requests in 10.00s, 100.65MB read
Requests/sec:  81219.67
Transfer/sec:     10.07MB
anonymous
()
Ответ на: комментарий от AndreyKl

Вот только раст в целом эффективнее Go, а запросы это обычно не просто «отдать статическую строку».

Зависит от области применения: если это просто веб-приложение-прослойка между API и базой, раст не особо нужен.

Если обработка запроса предполагает какие-то вычисления, раст выиграет скорее всего в целом будет эффективнее сервить.

Сравнение реализации HTTP-либ, которые у Go, очевидно, более взрослые != сравнение языков. Сравнить c tower-rs еще было бы интересно, хотя быстрее чем tokio-minihttp он вряд ли будет. (но tokio-minihttp однопоточный, насколько я знаю)

А вообще, не занимайтесь хренью, всё давно уже пробенчмаркано на http://www.techempower.com/benchmarks/ c кучей ревью.

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

Юзеры да, проблема, но еще при некоторых условиях ответ присоединяется не к тому посту. По-моему, это происходит, при ответе на последний пост топика, когда между нажатием на «Ответить» и «Поместить» в топик добавляется сообщение.

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

Что-то связанное с экзистенциальностью

Экзистенция — бытие, существование. Экзистенциальный тип это существующий тип.

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

Математики, конечно, могут корректнее меня описать идею).

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от tailgunner
fn belochka<T: Foo>() -> Foo

Для конпеляции такого кода нужны HKT, нет? И это ни разу не

аналог "-> impl Trait"

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

Почему тогда не взять си? на нём можно найти веб фреймворк, полагаю, и он наверняка «уделает» по «скорости» и раст и го.

Вносите Эдика.

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

Сразу вспоминается D с его vibe.d, который в своё время был самый быстрый, но это ему не помогло.

В смысле «не помогло»? У D все хорошо, язык растет и развивается, конференции проходят, коммерческих пользователей все больше и из различных областей - от веба до ембедщины. И все это без всякого хайпа. По продуктивности уж всяко лучше Rust. А по безопасности уступает, да. Просто в Rust в угоду безопасности все принесено, в том числе и продуктивность. А в D аккуратно сочетаются различные подходы. Кому нужен именно инструмент для решения задач просто выбирают подходящий инструмент и его используют. Не важно - Rust, D или Go. Они просто берут и делают. Остальные сидят на форумах и обсуждают кто круче, а «кому не помогло». Вместо того, чтобы делом заниматься)))

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

Зачем мне безопасность, у меня нет времени думать о ней, лучше ещё раз ААААА ПРОГРАММА ВЫПОЛНИЛА НЕДОПУСТИМУЮ ОПЕРА

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

Сразу вспоминается D с его vibe.d, который в своё время был самый быстрый, но это ему не помогло.

В смысле «не помогло»?

В смысле, D примерно как Dart. Тот тоже развивается и живет, но получилось ли у них потеснить C++ и JavaScript соответственно?

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

При этом вопрос стоимости разработки и сопровождения ты совершенно упускаешь из виду. Мягко говоря странно.

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

Почему тогда не взять си? на нём можно найти веб фреймворк, полагаю, и он наверняка «уделает» по «скорости» и раст и го.

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

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

В смысле, D примерно как Dart. Тот тоже развивается и живет, но получилось ли у них потеснить C++ и JavaScript соответственно?

Да ну не стоит мыслить категориями «поработить мир». Как говорит дедушка Путин - мир уже давно стал многополярен и нужно жить в этом новом мире. Не будет одного универсального языка, на котором будут писать все. Потому что такой универсальный язык будет решать все задачи одинаково плохо.

Си с плюсами играли такую роль просто потому что они были первые и люди еще только накапливали тот опыт, который сейчас реализуется в том же Го или Расте. Тот же D обладает такими выдающимися возможностями во многом за счет того, что учли ошибки плюсов.

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

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

Всегда было, по крайней мере очень давно, он же парный тег.

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

Да ну не стоит мыслить категориями «поработить мир».

Я не писал о глобальном господстве, речь шла о конкурентности, которой на данный момент не пахнет, одни локальные победы.

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

Ну и по скорости я бы не сказал, что Го или Раст сильно уступают чистым сям, на уровне статистической погрешности скорее всего.

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

gcc-go (т.е. неоригинальный ГНУтый компилятор языка Go) и чистый Си в лице gcc — обе являются фронтендами бекенда GCC. Да и в этом случае чистый Си никто не обгонит.

Есть реализация Go в котором он является фронтендом к LLVM.

Rust — это фронтенд компилятора LLVM.

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

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

Вместо того, чтобы делом заниматься

Это вы про себя? Я уже давно с языком определился и на лор захожу что бы поржать с клоунов.

По продуктивности уж всяко лучше Rust.

На 146% надеюсь?

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

А значит и стоимость разработки и сопровождения?

Как вообще можно сопровождать Go?

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

Качественный кодер на си, который сможет написать качественный, чистый код, который решает поставленную задачу оптимальным образом требует высокой квалификации и такой кодер будет иметь годовой доход сильно выше чем у программиста Го или Раста

С чего бы? Если решение «поставленной задачи» можно написать на Rust или, прости ТНБ, на Go - с чего бы платить Си-программисту больше?

эти коммерческие пользователи не такие крупные, конечно, как Гугл у Го или Мозилла у Раста, но в этом тоже есть преимущество - куча мелких даже более надежна чем один крупный.

А у D много мелких коммерческих пользователей? Откуда данные?

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

Вы реально считаете, что продуктивность программиста го меньше чем оная у программиста на расте?

Я реально считаю что это очень важные параметры и в совокупности они на мой взгляд однозначно перевешивают пресловутые 17% разницы (если она есть, это ещё вопрос на самом деле, бенчи честно говоря уж слишком наколеночные).

И я об этом прямо сказал. С чего вы взяли что я считаю что раст лучше го я не знаю. По крайней мере я этого точно не говорил.. ну или приведите цитату.

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

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

С чего вы взяли что я считаю что раст лучше го я не знаю.

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

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

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

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

«Side note for you type theorists out there [...] impl Trait is universal in an input position, but existential in an output position.» Почему так - опять же ХЗ,

ммм... а может быть как-то по-другому среди нормальных людей? мне правда интересно — это вопрос выражения мыслей

например, «кофемолка мелет кофе» означает, что она принимает на вход зерна _любого_ сорта кофе, при этом результат — молотый кофе, для которого _существует_ определенный сорт (он, кстати, может и отличаться от сорта кофе на входе — точнее, быть его субтипом/суб-trait-ом/субсортом — если она кофе еще и жарит дополнительно, скажем)

другой вариант: покупка билета на поезд

если мы что-то не специфицировали на входе (например, содержимое чемодана), то пользователь может запихнуть _любое_ содержимое; если мы что-то не специфицировали на выходе (например, точный номер места), то значит этот номер _существует_, но будет место верхним, нижним, или у туалета — сказать нельзя (кстати, в ржд есть даже билеты где «место указывает проводник»)

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

а может быть как-то по-другому среди нормальных людей?

Я вообше не считаю, что impl Trait нужен на месте аргумента.

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

Я вообше не считаю, что impl Trait нужен на месте аргумента.

я как раз про это хотел написать

допустим, объекты Т это животные, impl Trait означает что животное можно перевезти в купе поезда (или на легковой машине — короче, не слон и не кит), а функция — это трансфер из города в город; на входе животное в одном городе, на выходе — оно же, но в другом городе

ммм... невнятно написал, но идея видимо ясна

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

Это термин из Scala. Возможно, что здесь как раз кванторы меняются местами как при отрицании, но мне не охота тратить время на обдумывание этого.

Вообще, поражаюсь языку Rust. Мало того, что быстрый как Си, так еще и позволяет естественно выражать монадические вычисления. На Си++ такое заколебешься делать. И еще непонятно, получится ли, вообще, сделать такое на Си++.

Если кто не в курсе, то ваши любимые вычисления из future-rs - пример монадических вычислений. Не совсем точная монада, потому что вмешивается передача вычислений по значению (move), но в целом идея та же. Но именно из-за того, что передачу по значению довели до совершенства, такое и возможно запрограммировать на системном языке Rust без сборщика мусора.

Вот, на Си++ просто не представляю как делать, если совсем уже не извращаться, но так писать там на Си++ точно никто не будет (и не сможет). А вот на Rust пишут и во всю, даже многие не подозревая об этом. Да и итераторы тоже очень близки к монадическим вычислениям, и иногда ими являются. Там же есть once и flat_map)

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

Top secret) посмотри реализацию futures-rs. Метод and_then у трейта это и есть знаменитая функция (>>=). А сам трейт - по сути тип монады. Только операции типа and_then приводят к созданию структур, которые снова реализуют трейт. Так мы остаемся в рамках вычисления. Если хотим его продолжить на основе предыдущего, то и вызываем and_then. Там же все на поверхности, просто нужен некоторый базис ФП, чтобы это понимать.

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

Я не писал о глобальном господстве, речь шла о конкурентности, которой на данный момент не пахнет, одни локальные победы.

В смысле не пахнет? Если люди строят свою инфраструктуру на D, выбирают его, это разве не конкурентность?

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