LINUX.ORG.RU

Я познаю Rust: Лайфтаймы

 ,


2

5

Пытаюсь разобраться как работать с лайфтаймами:

use std::collections::LinkedList;

struct Point {
    x: f32,
    y: f32,
}

struct Rectangle<'a> {
    p2: &'a Point,
    p1: &'a Point,
}

fn main() {
    let mut list = LinkedList::new();
    let point1 = Point { x: 0.3, y: 0.4 };
    let point2 = Point { x: 0.3, y: 0.4 };
    
    let rect = Rectangle { p1:&point1, p2:&point2};
    list.push_back(rect);
    list.clear();
}

Как правильно очищать список, чтобы компилятор не ругался на point1, point2?

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

Стоп. Так Mxx_ru - это ваша поделка? Замечательно, то есть мне еще и систему сборки свою нужно запилить для этой фичи?

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

Ну если ты тормозишь на C++ 10 летней давности

Предпочитаю термин «C++0x».

то давай тамошний C++ сравнивать с тамошним Rust-ом

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

Ну вот нет в C++ такого же стандарта, как Cargo в Rust-е,

Есть GNU make. Впрочем, у меня всё равно нет gcc 5.4.

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

Ага. При условии, что кодировка однобитная. Но кого это волнует.

Однобитная? Серьезно? Если ты хотел сказать однобайтная, то данный пример прекрасно сработает с UTF-8.

Но кого это волнует.

Тех, кто не знает про существование UTF-8.

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

Только не тогда, когда задача состоит в том, чтобы хранить указатель на объект, а не сам объект, в структуре.

Не решайте глупых задач и жить станет проще.

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

Даже сравнение Си++ с Rust не имеет большой ценности - просто потому, что в Си++ нет главных фишек Rust

В Rust тоже шаблонов и классы не завезли.

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

Но если уж хочется сравнить, сравнивать надо стандартные средства, - стандартный язык и стандартную библиотеку.

Они тоже не эквивалентны по наполнению. У C++ нет работы с ФС, у Rust, например, рандома. Да и политика развития stdlib у языков разная.

Если уж сравнивать, ИМХО, то возможности языков и код соблюдающий принятые конвенции, то есть код, написанный именно на идиоматичном Rust и на идиоматичном C++, а не просто с использованием синтаксиса.

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

Что под видной делать или под маком?

Тоже самое.

Или на лине gcc 4.9.4?

А на QNX, Solaris или NonStop, где Rust-ом не пахнет? Или если у вас только какой-нибудь Rust 1.0 из коробки и все?

Так Mxx_ru - это ваша поделка? Замечательно, то есть мне еще и систему сборки свою нужно запилить для этой фичи?

Для какой фичи? У меня впечатление, что у местных растоманов увлечение Rust-ом отключает мозг.

Я привел пример нормального C++ кода, который компилируется и работает. Т.к. tailgunner попробовал включить дурочку, то я ему скинул весь проект, на котором проверялась работа. Хочет удостовериться в работоспособности — сможет проверить.

Поскольку в C++ нет менеджера зависимостей, то внешние либы (ranges-v3 и fmtlib) все равно пришлось бы как-то подтягивать. Хоть через CMake, хоть через какой-нибудь Conan, хоть через vcpkg, хоть через Nuget, хоть через git submodules или hg subrepos. И всегда нашелся бы кто-то, кто бы сказал — так это мне еще чего-то ставить нужно?

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

Предпочитаю термин «C++0x».

Ага, и C++14 в природе не существует.

Зачем?

Затем, что RazrFalcon именно что сравнивал «многословность» C++ и лаконичность Rust-а. Глупость такого сравнения и была продемонстрирована.

Но если уж хочется сравнить, сравнивать надо стандартные средства, - стандартный язык и стандартную библиотеку.

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

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

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

Если ты хотел сказать однобайтная, то данный пример прекрасно сработает с UTF-8.

Очепятка. И как она работает?

char str[] = "1234 678 1234567";
0: 1234
5: 678
9: 1234567

char str[] ="Löwe 老🐱虎 Léopard";
0: Löwe
6: 老🐱虎
17: Léopard

Ой. Не работает что-то =)

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

В Rust тоже шаблонов и классы не завезли.

Шаблоны есть через дженерики и макросы.

Классы - понятие растяжимое. Некое подобие есть.

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

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

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

Вы привели тот же самый код, убрав оттуда begin()/end() и зачем-то заменив cout на fmt. Всё. Что это должно было показать - не ясно.

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

Ой. Не работает что-то =)

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

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

Глупость такого сравнения и была продемонстрирована.

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

Плюсовый код по прежнему многословней.

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

Вы привели тот же самый код, убрав оттуда begin()/end() и зачем-то заменив cout на fmt. Всё. Что это должно было показать - не ясно.

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

Все это проделывается в вариантах на обоих языках. Но вариант на C++ вы считаете более многословным. Может я совсем уже тупой, но многословность там можно увидеть разве что в тех самых begin()/end() и cout/endl. Эта многословность не является «родовым» пятном C++, легко можно писать и без этого. Пример чего вам и был продемонстрирован.

Все еще не ясно?

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

Кому оптимальнее?

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

Сам придумал задачу. Сам её решил. И теперь доволен. Красота.

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

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

А ты ожидал, что компилятор умен, как ты? P_P

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

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

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

Ok, я понял что вы хотели сказать: код на C++ с использованием только стандартной библиотеки C++ будет многословнее кода на Rust-е с использованием только стандартной библиотеки Rust-а.

Так и запишем.

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

Прежде чем обвинять окружающих, посчитали бы буковки и слова.

Я даже сделаю это за вас:

std::vector<int> v{ 1, 2, 3, 4 };
auto r = ranges::find_if(v, [](int i){ return i % 2 == 0; });
if (r != end(v)) {
    fmt::print("{}\n", *r);
}
let vec = vec![1, 2, 3, 4];
if let Some(v) = vec.iter().find(|i| *i % 2 == 0) {
    println!("{}", v);
}

Вывод wc:

      5      28     145
      4      21     105

Ой!

PS: не переживайте из-за закрывающей фигурной скобки. Она там нужна. Мы же не однострочник пишем.

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

Ещё раз: изначально была задача «разбить строку». Вы влезли со своим непонятным решением, которое нарушает UTF-8. Где ещё глупость?

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

C++ в любом случае будет многословней. Даже если вам хочется обратного. Ибо у раста нет ноши совместимости с С.

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

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

Давайте еще подсчитаем выигрыш от использования f64 в сравнении с double, тут ведь вообще синтаксический оверхед в цельных два раза!

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

Ещё раз: изначально была задача «разбить строку». Вы влезли со своим непонятным решением, которое нарушает UTF-8. Где ещё глупость?

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

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

Вы не можете понять, что один код короче другого, но дебил я. Логика/0.

Если не хотите считать символы - посчитаем действия. В rust не нужно создавать отдельную переменную с результатом, а потом сравнивать её с «концом» вектора, а C++ нужно. Всё остальное идентично. То есть даже таким методом rust получается «короче».

Если вы всё равно не довольны - приведите свой метод подсчёта. А то врываетесь в тред, обвиняя всех дебилами, но методом расчёта вашей «лаконичности» не делитесь.

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

Ты бредишь. Во-первых задачу ставил я.

Из сотен муханонимусов не разобрать.

но облажался

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

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

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

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

Если вы всё равно не довольны - приведите свой метод подсчёта.

Блин, да вы еще и читать не умеете, может школу еще не закончили?

Все уже давно расписано:

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

Все это проделывается в вариантах на обоих языках.

Ну растоман же не читатель, он же пейсатель:

В rust не нужно создавать отдельную переменную с результатом, а потом сравнивать её с «концом» вектора, а C++ нужно.

Ой, правда шоли? А как быть вот с этим if let Some(v)? Тоже самое, только вид в профиль. И v вам объявлять пришлось, и if писать.

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

Какие ещё примеры?

Да хотя бы примеры с зацикленным графом объектов и использованием коллекций на полях структур для работы с объектами. Самый простой пример Article-Comments

Я кое-что подобное нашел на гитхабе, но там куча clone операций с такими объектами. Похоже в расте не только с иерархией структур беда, но и работа с бизнес доменами осложнена.

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

А как быть вот с этим if let Some(v). Тоже самое, только вид в профиль. И v вам объявлять делать, и if писать.

В C++ - это занимает две строки кода и две отдельные инструкции (присвоение результата и условие). В rust - это одна строка, и одна инструкция (if let, да, сахар).

Получается, на C++ мне нужно написать больше текста (факт), но это не важно, написать больше инструкций (факт), но это не важно, и в итоге C++ короче rust.

Но виноват опять я. Да?

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

Код нерабочий. То, что вы представляете строки по своему, не делает ваше решение верным.

Т.е. я теперь не только «влез» с решением, но еще и не понимаю условие задачи. Шикарно.

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

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

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

Вместо графа объектов Article-Comments можно представить в виде хэш-таблиц.
А если прям нужен граф и на нем надо пыполнять графовые алгоритмы, то это совсем другая задача, которая, кстати, эффективнее всего решается через те же хэштаблицы)
Еще распространен вариант с хранением таких структур в линейной памяти (не будуту же Вы, право, хранить граф в виде связных списков?)

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

Да хотя бы примеры с зацикленным графом объектов

А что с ними не так? Есть готовый petgraph. Можно свой сварганить.

использованием коллекций на полях структур для работы с объектами

Не распарсил.

но там куча clone операций с такими объектами

Методов clone()?

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

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

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

(if let, да, сахар).

Да сахар. Об этом я и говорю. Что в вашем примере сравнивается именно что сахар и на основании сравнения сахара декларируется выигрыш Rust-а.

Это такой же дебилизм, как и сравнивать f64 с double, о чем я здесь уже в третий раз говорю, но до вас все никак не доходит.

написать больше инструкций (факт)

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

Весь дальнейший разговор это только подтвердил.

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

но еще и не понимаю условие задачи

Если у вас строки могут быть только в однобайтной кодировке - тогда всё ок.

Вот хочу я обрезать строку, чтоб начиналась со второго слова, и просто делаю присваивание указателя, что плохо случится?

Лол. Я уже привёл пример того, что случится - сломается всё.

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

Да сахар. Об этом я и говорю. Что в вашем примере сравнивается именно что сахар и на основании сравнения сахара декларируется выигрыш Rust-а.

В многословности? Да, именно так.
Иначе можно дойти до того что ассемблер не более многословен чем си, так как операторы, условные конструкции и циклы — это всего лишь сахар. Объясните свой критерий многословности пожалуйста, чтобы мы тоже понимали какими категориями вы мыслите.

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

Да сахар. Об этом я и говорю.

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

Что в вашем примере сравнивается именно что сахар и на основании сравнения сахара декларируется выигрыш Rust-а.

Да! Сахар, шок!, позволяет писать меньше кода, делая понимание алгоритма более простыми. Но вы утверждаете, что это всё фигня.

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

Может еще выхлоп ASM почитаем. Там вообще красота.

Делать из такого сравнения выводы о большей/меньшей многословности языка

То есть необходимость писать в 1.5-2 раза больше кода - это не многословность?

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

C++ - это занимает две строки кода и две отдельные инструкции (присвоение результата и условие). В rust - это одна строка, и одна инструкция (if let, да, сахар).

Внезапно в С++ это занимает ровно столько же:

if( auto o = iter( v ).find_if( ... ) )
   cout << *o;

Достаточно добавить функцию-шаблон iter, которая вернет обертку с методом find_if, которая вернет std::optional. Это уже чисто библиотечный вопрос, и, да, для данного конкретного случая в С++ дела обстоят хуже.

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

Ну то есть цена одной строки — несколько строк на написание шаблонной функции.
Если так, то можно просто написать функцию «print_if», которая принимает шаблонный объект и лямбду. Красота, всего одна строка, C++ охеренен.

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

Объясните свой критерий многословности пожалуйста, чтобы мы тоже понимали какими категориями вы мыслите.

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

int * p = 0;
for( size_t i = 0; i < ASIZE(v) && !p; ++i )
  if( 0 == v[i] % 2 )
    p = &v[i];
if( p )
  printf(...);
более многословна, чем запись:
auto it = ranges::find_if( v, [](auto i) { return 0 == i % 2; } );
if( it != end(v) )
  printf(...);
Поскольку действий выполняется больше и контролировать правильность выполнения этих действий приходится более тщательно.

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

Теперь я понял эту точку зрения. Но придираясь к словам встать Вам, хочу заметить что «более многословный» — это «требующий больше слов» и на данных примерах C++ таки более многословный, хоть это и нихрена важного не значит

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

Нет. Ибо эта ваша функция iter тоже учитывается. Такими темпами можно вообще весь нужный сахар самому написать. Только зачем, если в rust это из коробки.

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

Продолжая вашу логику - C просто сахар над ASM.

Не-не-не, не нужно отображать свою логику (точнее ее отсутствие) на меня.

позволяет писать меньше кода, делая понимание алгоритма более простыми.

Подсчитайте же уже количество операций, которые нужно сделать и там и там. Убедитесь, что разница не велика. Вам нужно указать диапазон для поиска, вам нужно вызвать find_if, вам нужно дать лябду в find_id, вам нужно куда-то принять результат поиска, вам нужно проверить результат поиска на валидность, вам нужно выполнить печать.

Все это делается в обоих вариантах. Причем практически эквивалентно. С разницей лишь в синтаксисе. О чем я вам не перестаю говорить.

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

Ну так в примере с rust ещё меньше действий, ибо нет лишней переменной в области видимости функции.

Вы уже сами себе противоречите.

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

Нет. Ибо эта ваша функция iter тоже учитывается. Такими темпами можно вообще весь нужный сахар самому написать. Только зачем, если в rust это из коробки.

В питоне я могу поднять http-сервер одной строкой. В rust - нет. Вывод - rust дофига многословный, примитивный и ненужный язык.

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