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?

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

Убедитесь, что разница не велика.

То есть теперь вы согласны, что код не идентичен?

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

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

В том-же haskell это, небось, займет вообще с десяток символов. Но по вашей логике, C++ всё равно не многословнее, ибо операции то те же. Мне это решительно непонятно.

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

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

Мозги, наконец, включите. Вы видите эту «лишнюю» переменную, хотя в упор не видите, что вам приходится писать Some(v) для тех же самых целей. Вы не видите, что в Rust-овом варианте вам нужно разыменовывать итератор, тогда как в C++ном вам уже готовый экземпляр подсовывают.

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

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

Правда не ясно, кто мешает сделать это в rust.

Старые маразматики, которые не понимают, что кол-во символов в программах и жирная стандартная библиотека решают все.

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

То есть вы правы потому, что вы правы. Так?

Еще раз повторю, здесь различия в операциях на уровне статпогрешности.

Цитирую (Я познаю Rust: Лайфтаймы (комментарий)): «Плюсовые итераторы верх лаконичности.»

Поясняю: лаконичность (ака краткость), в моём понимании, зависит от количества текста на экране, а не от количества операций (явных или нет).

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

жирная стандартная библиотека решают все.

Ага, особенно в питоне, где пакеты попавшие в stdlib фактически перестают развиваться.
Питонщики даже шутят про «место, куда модули уходят умирать»

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

То есть вы правы потому, что вы правы. Так?

Нет, не важно, насколько прав я. Важно, что то, на чем настаиваете вы, — это детский сад.

в моём понимании, зависит от количества текста на экране, а не от количества операций (явных или нет)

Да это не просто детский сад, это какая-то младшая ясельная группа.

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

Ага, особенно в питоне, где пакеты попавшие в stdlib фактически перестают развиваться.

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

Питонщики даже шутят про «место, куда модули уходят умирать»

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

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

Кажется, именно это называется «синдромом утенка».

Кажется, это называется «мнение от человека, который не использует rust и не умеет на нем писать что-то либо сложное».

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

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

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

У меня нет возможности его использовать, а как язык он мне не интересен. Так что да, не существует.

Затем, что RazrFalcon именно что сравнивал «многословность» C++ и лаконичность Rust-а

Ну, ему это нужно. Мне - нет.

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

Повторюсь - если не ограничиваться стандартной библиотекой, можно всегда писать «сделать_зашибись()».

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

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

Кажется, именно это называется «синдромом утенка»

Кажется, это называется «мнение от человека, который не использует rust и не умеет на нем писать что-то либо сложное».

«Кажется»? Это так и есть, я об этом не раз говорил. Но мое мнение обо всем на свете таково.

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

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

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

Не эквивалентны, но близки. Да и рандом с ФС от языка зависят не сильно.

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

У меня нет возможности его использовать

Как будто Rust у тебя есть возможность использовать.

а как язык он мне не интересен. Так что да, не существует.

Зашибись логика. Мне, например, Rust не интересен, это же не значит, что его не существует. Или значит?

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

Как будто Rust у тебя есть возможность использовать.

В отличие от Си++, Rust мне интересен.

Мне, например, Rust не интересен, это же не значит, что его не существует. Или значит?

Для тебя - значит (значило бы). Но он тебе интересен, иначе тебя здесь не было бы. Да и странно было бы, если бы кому-то, связанному с системным программированием, бы не интересен Rust. Взлетит он или нет, но он уже влияет на новое поколение языков.

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

Для тебя - значит (значило бы).

Это какая-то ерунда. Существование языка (версии стандарта языка) — это объективная штука, которая не зависит от интереса к нему конкретной личности.

Но он тебе интересен, иначе тебя здесь не было бы.

Как язык (т.е. как сборище каких-то языковых фич и подходов) не интересен. А вот как нечто, что может существенно уменьшить нишу плюсов, Rust привлекает мое внимание. Какое влияние он окажет на будущие поколения языков опять же не интересно. А вот то, придется ли переписывать свои инструменты на Rust, чтобы найти свое место на будущих рынках — вот это интересует.

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

Такого уровня аргументации я не ожидал.

Ну смотрим на этот самый уровень:

лаконичность (ака краткость), в моём понимании, зависит от количества текста на экране, а не от количества операций (явных или нет).

Это означает, что между s=w*h и square = width * height существует просто катастрофическая разница в лаконичности.

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

vec.iter().find(|i| *i % 2 == 0)
std::find_if(vec.begin(), vec.end(), [](int i){ return i % 2 == 0; });

И чем это отличается от сравнения s=w*h и square = width * height?

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

Это библиотечные методы, а не мои переменные.

Я фигею, дорогая редакция. Что уж говорить тогда про find(vec, _1 % 2 == 0);.

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

Он понимает, что мы передали ownership в list

Разве там передается владение? Ссылки-то не mut. Конпелятор жалуется, что остались ссылки на дропнутые ресурсы.

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

Уйми свой генератор желчи, серьезно. С тобой становится очень неприятно общаться.

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

А как же вдоль?)

Virtuos86 ★★★★★
()

Можно как-то запретить eao197 писать в топики о Rust? Он, конечно, старается быть объективным и корректным, но слишком часто либо провоцирует срач, либо его поддерживает.)

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

Предлагаю такое определение нелаконичности: количество мест, которые придётся править при копипасте. Т. е. «collection.LockCollectionAndGetForwardIterator()» лаконичнее чем «c.begin(), c.end()», потому что при копипасте во втором случае придётся править название коллекции в 2х местах. Ну и, соответственно, if let Some(v) лаконичнее, чем присваивание переменной и последующая её проверка, потому что не нужно следить за согласованностью присваивания и проверки.

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

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

Возьмем, для примера, простейшее объявление лямбды с одним аргументом-значением, возвращающую что-то, в Rust-е и в C++.

В Rust-е мы имеем список параметров и тело, в котором необязательно писать return: |i| i % 2 == 0.

В C++ мы имеем: список захвата, список аргументов (в котором недостаточно просто обозначить имя аргумента), тело в котором обязательно нужно указывать return. Т.е., как минимум, видим: [](auto i){ return i % 2 == 0; }.

Т.е. синтаксис лямд в Rust-е лаконичнее, чем в C++.

По поводу различий между:

if let Some(r) = ...
и
auto r = ...;
if( r == end(v) )...
тоже можно сказать, что Rust лаконичнее, хотя лаконичность эта уже более близка к сравнению f64 и double, ибо логических операций от пользователя в обоих случаях требуется одинаково (декларация переменной, присваивание ей значения, проверка валидности значения). Ну и не забываем, что в этом году уже будет разрешена запись:
if( auto r = ...; r == end(v) )
которая уберет еще один аргумент об ограничении области видимости.

Однако, если мы берем кусок кода чуть более объемный, чем простая лямбда (тот же фрагмент, на котором начал спекулировать RazrFalcon), то мы увидим, что мелкие выигрыши Rust-а мало заметны на том большом количестве действий, которые нужно сделать пользователю.

И это при том, что в C++ существует более одного способа достичь того же самого результата. Пара из них и была показана.

Так что исходный тезис RazrFalcon-а о том, что «По сравнению с C/C++ - в rust намного меньше писанины» не был должным образом подкреплен.

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

Ну и, соответственно, if let Some(v) лаконичнее, чем присваивание переменной и последующая её проверка

Ну и кстати по этому поводу. Rust-овый и C++ный варианты не полностью эквивалентны по выполняемым действиям. В Rust-а мы сразу получаем optional с первым элементом, который удовлетворяет предикату. Тогда как в C++ мы имеем итератор. Из-за этого нам приходится сравнивать два итератора дабы понять, найден ли элемент или нет.

Однако, если у разработчика в руках API, в котором есть find, возвращающий optional, то запись и в C++ могла бы быть вот такой:

if(auto r = find(..., predicate)) {...}

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

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

Однако, если у разработчика в руках API, в котором есть find, возвращающий optional, то запись и в C++ могла бы быть вот такой:

В Rust можно не только optional в if let проверять, это просто синтаксический сахар к match, которого в C++ нет и не планируется.

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

Спасибо за напоминание.

Да, вот enum-ы и match в Rust-е способны дать приличный выигрыш в лаконичности и выразительности кода по сравнению с C++.

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

Да, вот enum-ы и match в Rust-е способны дать приличный выигрыш в лаконичности и выразительности кода по сравнению с C++.

А могут и наоборот. В коде того же servo полно кода, который легко записывается в С и С++ тернарным оператором (a ? a->b : 0), а в Rust вместо него многострочная конструкция из match, Some, None.

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

В коде того же servo полно кода, который легко записывается в С и С++ тернарным оператором (a ? a->b : 0), а в Rust

a.map_or(0, |a| a.b);
O02eg ★★★★★
()
Ответ на: комментарий от O02eg

a.map_or(0, |a| a.b);

Лаконично (хоть и не на уровне тернарного оператора), но код превращается в перловку.

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

Это было к тому, что многие жаловались на «многострочную конструкцию из match, Some, None.»

Не надо подменять понятия, «многие» «жаловались» на отсутствие тернарного оператора. Причем «многие» понимают, что к if/else и match лучше не добавлять третью сущность, но в отдельных случаях она бы помогла писать более лаконичный код без потери читабельности.

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

Это какой-то бред. Тернарный оператор работает только для булевой логики и писать match в таких местах — антипаттерн Rust'а. Вместо тернарного оператора используется конструкция if-else

let result = if a {1} else {0};
А вот match используется там, где тернарный оператор никаким боком не поможет:

enum A {
   B(u32),
   D(u32, u8, String, Vec<u64>)
}

match a {
   A::B(c) => println!("A::B({})", c)
   A::D(e, ..) => println!("A::D({}, ..", e)
}

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

Это какой-то бред. Тернарный оператор работает только для булевой логики и писать match в таких местах — антипаттерн Rust'а. Вместо тернарного оператора используется конструкция if-else

Так это ваши проблемы, что у вас через что работает и что антипаттерн. Тернарный оператор вполне себе мог бы работать с Result или Option.

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

Тернарный оператор вполне себе мог бы работать с Result или Option.

Ага, в Си.

anonymous> коде того же servo полно кода, который легко записывается в С и С++ тернарным оператором (a ? a->b : 0), а в Rust вместо него многострочная конструкция из match, Some, None

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

Ну и не забываем, что в этом году уже будет разрешена запись:

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

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

Ага, в Си.

Ну да. Если фанаты раста распереживались, что их язык ругают, то им стоит остыть и понять, что речь идет как раз о том, как можно писать в опасных и старых С и С++. И что в последнем std::optional (который страшно опасный и которого еще нет) работает в связке с тернарным оператором за счет неявного приведения типа. Потому местами на С++ код можно записать короче чем на Rust, где все более правильно и жестко.

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

В C++ это нужно потому, что нету паттерн матчинга. В Rust нет необходимости проверять, что Option содержит значение, а потом забирать его. Поэтому и тернарный оператор не нужен.

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

В Rust нет необходимости проверять, что Option содержит значение, а потом забирать его. Поэтому и тернарный оператор не нужен.

Ну не нужен так не нужен, ваше дело, но это же не отменяет того факта, что кода пишется больше.

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

Если фанаты раста распереживались, что их язык ругают

Нет. Фанаты Rust указали на простой факт: то, что в Си и Си++ делается тернарным оператором, в Rust делается oбычным if-else, а не match, как сказал ты.

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

Фанаты Rust указали на простой факт: то, что в Си и Си++ делается тернарным оператором, в Rust делается oбычным if-else, а не match, как сказал ты.

Тогда могу посоветовать этим фанатам начать уже писать что-то на Rust, потому-что if у них используется в фантазиях, а такое:

                    let bidi_level = match bidi_levels {
                        Some(levels) => levels[*paragraph_bytes_processed],
                        None => 0
                    };

На самом деле.

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

С чего бы это? Повторяю: в Rust нет необходимости отдельно проверять и забирать значение Option.

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