LINUX.ORG.RU

Вышел Rust 1.23

 ,


2

9

4 января состоялся плановый релиз компилятора и стандартных средств разработки системного языка программирования Rust — 1.23.

Интересные изменения:

  • За счёт предотвращения ненужного копирования аргументов функций уменьшено потребление памяти. Например сам компилятор rustc стал потреблять на 5-10% меньше памяти.
  • rustdoc перешёл на рендеринг документации при помощи CommonMark. Раньше использовался Hoedown.
  • The Cargo Book переехал с doc.crates.io на doc.rust-lang.org и обновил формат.
  • cargo uninstall научился сразу удалять несколько пакетов. Например, команда cargo uninstall foo bar удалит foo и bar.
  • auto трейты теперь разрешены в трейтовых объектах. Один из коммитов этого изменения также окончательно удалил элемент языка send.
  • Проверки типов операндов бинарных операторов теперь производится относительно левого операнда, что предотвращает путаницу в соответствующих сообщениях об ошибках.
  • Исключена необходимость в T: Sync для RwLock<T>: Send.
  • Исключена необходимость в T: Sized для {<*const T>, <*mut T>}::as_ref и для <*mut T>::as_mut.
  • Оптимизирована реализация Thread::{park, unpark}.
  • Улучшена производительность SliceExt::binary_search.
  • Трейт AsciiExt объявлен устаревшим, а его методы перенесены в примитивные типы.
  • char::escape_debug теперь использует Unicode 10 вместо Unicode 9.
  • Включён LLVM-флаг TrapUnreachable.
  • musl, используемый для сборки musl rustc, обновлён до 1.1.17.
  • Улучшена производительность SliceExt::binary_search.
  • rustfmt включён в основную инсталляцию.
  • Минимальная версия LLVM изменена на 3.9.

Полный перечень изменений

>>> Анонс

★★★★★

Проверено: Shaman007 ()

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

Расскажи мне про ручное управление памятью в Rust.

https://doc.rust-lang.org/1.15.0/alloc/heap/fn.allocate.html

Ну и какое отношение это имеет к drop?

Ты просил рассказать о ручном управлении памятью в Rust - я рассказал. Если ты не понимаешь роли деструкторов в ручном управлении памятью - твои проблемы. Если не понимаешь, что в деструкторе можно вызвать deallocate - опять же твои проблемы.

Значит что делать с твоими метками функций с panic ты так и не расскажешь?

Я рассказал. Ты просто не понял.

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

У Rust не автоматическое.

Есть необходимость самому освобождать память? Как это делается, есть аналог delete из C++?

С чего бы это вдруг? А Arc/Rc по вашему как работают?

«забывает» об объекте и он удаляется рантаймом так же, как обычный объект после выхода их скопа. Разве не это делает forget(this); внутри него?

bbk123 ★★★★★ ()

Самое прекрасное в расте это то, что его уже внедряют комьюнити гстримера и гнума. Даст бог не придется больше шквариться о си и кресты никогда (ну или почти никогда).

Хотел потыкать раст, а потом узнал, что там нет исключений

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

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

Так проблема в этом, а не в оптимизации LLVM?

И в этом тоже. Разве не может больше одной проблемы?

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

Не получится. В местах, где паника недопустима, будет использоваться не foo, а foo.get(i).

И есть места рядом, где паника допустима, а отличить одни виды паник от других видов паник в сигнатуре функции не получится.

Следи за предупреждениями компилятора о недостижимом коде.

А это тут причем? Приведи пример кода

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

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

А что, уже есть такой синтаксис в языке?

Так проблема в этом, а не в оптимизации LLVM?

И в этом тоже.

Если считать это проблемой, обсуждать нечего.

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

Ты просил рассказать о ручном управлении памятью в Rust - я рассказал. Если ты не понимаешь роли деструкторов в ручном управлении памятью - твои проблемы.

Я это прекрасно понимаю.

Если не понимаешь, что в деструкторе можно вызвать deallocate - опять же твои проблемы.

Ты дал ссылку на allocate. Ну хорошо, в std::heap::Alloc есть deallocate и всё это предназначено для unsafe. Но как это делает drop деструктором? Разве он вызывается из deallocate или в Rust есть аналог delete из C++?

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

Но как это делает drop деструктором?

Ты, наверное, единственный известный мне персонаж, который не называет drop деструктором.

https://doc.rust-lang.org/nomicon/destructors.html

«What the language does provide is full-blown automatic destructors through the Drop trait»

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

Если ты не обратил внимание, я лишь недавно начал интересоваться Rust-ом и принятой в нём терминологией ещё не проникся. По сути drop - это такой же финализатор, как finalize() в Java. Его определение в документации как «дестрактор» выбрано неудачно.

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

Если ты не обратил внимание, я лишь недавно начал интересоваться Rust-ом и принятой в нём терминологией ещё не проникся.

Но тем не менее ты уже объясняешь, что деструкторы в Rust - не деструкторы.

По сути drop - это такой же финализатор, как finalize() в Java

Если вложить в слова «по сути» подходящий смысл, можно приравнять что угодно к чему угодно.

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

This function is not magic; it is literally defined as

pub fn drop<T>(_x: T) { }

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

Но тем не менее ты уже объясняешь, что деструкторы в Rust - не деструкторы.

Они не делают полностью то, что делают деструкторы C++ и не вызываются оператором delete, которого в Rust нет. Они являются полными аналогами finalize() в Java и именно поэтому я их так называю. Ты можешь назвать хотя бы одно отличие от finalize() в Java?

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

Эм, тем, что детерминировано вызываются?

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

ты уже объясняешь, что деструкторы в Rust - не деструкторы.

Они не делают полностью то, что делают деструкторы C++

И чего же они не делают?

и не вызываются оператором delete, которого в Rust нет.

Ты так говоришь, будто деструкторы могут быть только в языках с delete.

Кстати, а приведи определение деструктора, которым ты пользуешься (то самое, которому деструкторы Rust не отвечают).

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

Они не делают полностью то, что делают деструкторы C++ и не вызываются оператором delete, которого в Rust нет.

Ты можешь назвать хотя бы одно отличие от деструкторов в C++ ?

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

Оно не всегда освобождает память - не аналогог delete в C++.

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

Оно не всегда освобождает память - не аналогог delete в C++.

Хм. Ты считаешь, что в Си++ память освобождается _деструктором_?

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

Есть необходимость самому освобождать память?

Если мы пишем свой контейнер с unsafe - то да, нужно. Посмотрите как стандартный контейнеры реализованы. Тут особой разницы с C++ нет. Ну кроме явного unsafe.

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

Из деструктора вызывает delete или free() полям класса, которые иначе могут остаться в памяти на всегда. Вот например:

class String
{
private:
    char *s;
    int size;
public:
    String(char *); // constructor
    ~String();      // destructor
};
  
String::String(char *c)
{
    size = strlen(c);
    s = new char[size+1];
    strcpy(s,c);
}
  
String::~String()
{
    delete []s;
}

В аналогичном коде на Rust или на Java не нужно удалять массив s, поскольку он удалится автоматически вмести с основным объектом. В C++ память этого массива освобождается именно деструктором.

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

Из деструктора вызывает delete или free() полям класса

Из drop это тоже можно делать. В чем твоя претензия, конкретно?

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

Что это? У тебя в Rust нет аналога delete - память управляется автоматически и как-то имитировать delete тебе просто не нужно. В коде на Rust, аналогичному выше приведённому, вообще нет необходимости в каком либо drop.

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

У тебя в Rust нет аналога delete

Тогда повторю вопрос - деструкторы могут быть только в языках с оператором delete?

И как насчет используемого тобой определения деструктора?

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

Тогда повторю вопрос - деструкторы могут быть только в языках с оператором delete?


Только в языках с ручным управлением памяти. Если память управляется автоматически, нет необходимости в ручном освобождении динамической памяти из деструктора. Иногда несть необходимость в финализации объекта перед его удалением. Именно для этого в Java есть finalize() и в Rust - drop.

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

В аналогичном коде на Rust или на Java не нужно удалять массив s, поскольку он удалится автоматически вмести с основным объектом. В C++ память этого массива освобождается именно деструктором.

Оторвись от Java. У Rust с C++ гораздо больше, чем с Java. Когда объект выходит из области видимости, вызывается деструктор этого типа. Деструктор в Rust — это Drop. Вот цитата оттуда:

Used to run some code when a value goes out of scope. This is sometimes called a 'destructor'.

В Rust, как и в C++, нет сборщика мусора, по-этому память в куче освобождается в декструкторе. Вот деструктор Box, освобождающий память.

impl<T: ?Sized> Drop for IntermediateBox<T> {
    fn drop(&mut self) {
        if self.layout.size() > 0 {
            unsafe {
                Heap.dealloc(self.ptr, self.layout.clone())
            }
        }
    }
}
anonymous ()
Ответ на: комментарий от bbk123

Тогда повторю вопрос - деструкторы могут быть только в языках с оператором delete?

Только в языках с ручным управлением памяти.

В Rust есть ручное управление памятью. Более того, всё построено именно на нем.

Если память управляется автоматически, нет необходимости в ручном освобождении динамической памяти из деструктора.

Что такое, по твоему, «автоматическое управление памятью» и почему ты считаешь, что его нет в Си++?

Определение деструктора ты дашь или нет?

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

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

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

Но в таких случаях как в примере выше это не работает, поэтому надо самому освобождать память. А в Java и в Rust - не надо.

На Java всем пофиг, а в Rust - тоже надо. Ну, если утечка памяти не является твоей целью.

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

Вот цитата оттуда

Я уже говорил, что считаю этот термин, в отношении drop, неудачным.

В Rust, как и в C++, нет сборщика мусора, по-этому память в куче освобождается в декструкторе.

Нет, там автоматическое управление памятью лишь реализовано иначе, но поскольку оно есть, освобождать память в том, что ты называешь дестрактором не нужно. В примере выше ты можешь вообще не реализовывать drop, а массив в динамической памяти всё равно удалится.

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

Наркоман? В расте как раз всё на смартпоинтерах. Если вы не видите знакомых слов (delete), то это не значит, что там всё не так.

Просто в Rust это запрятано черти куда, а в C++ на виду, в следствии наследия сишки.

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

В примере выше ты можешь вообще не реализовывать drop, а массив в динамической памяти всё равно удалится.

Нет. </thread>

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

Смартпоинтер - это один из видов автоматического управления памятью. По моему мы ходим по кругу.

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

В примере выше ты можешь вообще не реализовывать drop, а массив в динамической памяти всё равно удалится.

This is magic

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

Флоаты меня интересуют значительно меньше. а что за мой такой язык - я не знаю. На rust я не пишу, если что. Но если там поддерживаются IEEE флоаты (что очень вероятно), то нет там никакого UB.

А вот писать качественный переносимый код на C нереально. Разве что в коде glibc зайчатки разума присутствуют. А так чаще всего тихий ужас в любом проекте на C (из того, что видел).

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

Там через CPU планету хакают, не до Раста :)

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

главная проблема - весь этот ворох костылей нужно держать в голове и не забывать применять значительно чаще чем кажется. А пользуясь GNU C 1) уже теряем в переносимости 2) всё равно привязываемся к всеобщему любимцу публики x86.

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

Там через CPU планету хакают, не до Раста :)

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

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

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

Оправданием для вызова panic служит лишь полная невозможность продолжать работу. Если ты всё ещё можешь отправлять сообщения по сети или слать email-ы, то очевидно, что вызов panic неоправдан и если он всё же происходит, то это баг.

Есть recoverable и non-recoverable failure. Если ошибка внутренняя, в логике программы, тогда вообще нельзя доверять всему коду может быть и можно отправлять email-ы, но не понятно сработает ли это. Нужно сразу падать ничего не делая. Если ошибка вызвана отсутствием интернета, отсутствием какого-то файла, или другой внешней причиной, можно обрабатывать это.

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

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

Именно. Но зачем кому-то понадобится бросать panic в таком случае?

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

Наследование нужно, хотя бы для интерфейсов.

А интерфейсов, кстати, тоже нет. Вместо них предлагают какие-то трейты

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

Тогда и в C++ автоматическое управление памятью.

Нет, вернее далеко не везде. В частности тот класс (смотри пример кода на C++ выше) без деструктора будет течь.

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

А интерфейсов, кстати, тоже нет. Вместо них предлагают какие-то трейты

Чем трейт от интерфейса отличается?

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

Но в rust без Drop он тоже будет течь.

Каким образом? Если у меня есть объект A без Drop, который ссылается на объект B и объект A удаляется при выходие из скопа, разве не удалится так же и объект B, которым до этого владел A?

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

А вот писать качественный переносимый код на C нереально.

Почему, можно более развернуто пояснить причины?

Разве что в коде glibc зайчатки разума присутствуют.

О как! Первый раз вижу человека, который хвалит глибц.

Можешь обосрать https://github.com/shkolnick-kun/bugurtos ?

Аргументированно обосрать в духе Мужика-2?

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