LINUX.ORG.RU

Пытаюсь тут обмазаться ржавчиной.

 ,


0

4

Например вот такой кусок кода на Java:

public static void collect( Map<String, Boolean> map, List<String> list){
    map.entrySet().stream().filter( Map.Entry::getValue ).map( Map.Entry::getKey ).collect( Collectors.toCollection( () -> list ) );
}


и пытаюсь такое же применить в Rust
fn test_collect<'a>( map: &'a HashMap<String,bool>, vec: &mut Vec<&'a String> ){
	let mut cc:Vec<&String> = map.iter().filter(| &(_, v) | *v ).map(| ( k, _ ) | k ).collect();
	vec.append(&mut cc);
}


Что-то не нахожу как сделать без промежуточного вектора.

cast tailgunner, DarkEld3r

★★★★★

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

(в сторону) И чего это всех так одинарные кавычки возбуждают? Вспоминается дедушка Фрейд.

Это, конечно, намного красивее (куда const'ы ставить не помню).

#include <stdint>
void cp(int32_t *const* pp1, int32_t const*const*const pp2) {...

red75prim ★★★
()

Значит у обезьянок официально появился новый boundage and discipline идол - функциональное программирование.

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

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

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

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

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

Это структура, которая где-то по ходу програмы нахваталась ссылок с разных контекстов? Получается, если делать библиотечную структуру общего пользования, хранящую ссылки, то на каждую ссылку надо заводить свой лайфтайм?

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

Где тут мечты-то? Это летопись. На ЛОРе уже не одно поколение функциональщиков дверью хлопало, когда оно еще не было модно.

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

А перед лайфтаймом зачем «&»

Это указатель на указатель же. Вот тот указатель, НА который указатель имеет лайфтайм 'а

на самом деле можно вообще вот так записать

fn cp<'a, 'b>(pp1: &'b mut &'a i32, pp2: &'b&'a i32) {
    *pp1 = *pp2;
}

и это не будет ошибкой.

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

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

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

Жесть) После динамических язычков тяжко такое воспринимать

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

Это структура, которая где-то по ходу програмы нахваталась ссылок с разных контекстов?

Ага.

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

В 99% случаев вместо &'str в структуре лучше будет иметь String. Ну а в остальном - да. Если мы хотим, чтобы некие сущности (потенциально) имели разные лайфтаймы, то вынуждены заводить по отдельному лайфтайму на каждую из них.

DarkEld3r ★★★★★
()

1 | 2 => println!(«one or two»),
1 | 2

ref r => println!(«Got a reference to {}», r)
ref r

1 ... 5 => println!(«one through five»),
1 ... 5

Что за безумие. Почму не ||, &r и 1..5 ? Словно часть синтаксиса другого языка в match всунули.

Ох, там еще и @ для биндинга..

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

1..5

".." и "..." - это разные диапазоны: один включает правую границу, а другой нет. Правда сейчас немного дурацки что второй вариант только в матче и используется, а первый наоборот в нём использовать нельзя, но это хотят поменять и оба варианта, по идее, можно будет использовать везде.

&r

Дык, смысл разный. Без ref получается конкретный паттерн, который надо сматчить. И ты как раз предлагаешь наделить разным значением в зависимости от контекста.

Про || - хз.

Ох, там еще и @ для биндинга..

Твой вариант?

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

Дык, смысл разный. Без ref получается конкретный паттерн, который надо сматчить. И ты как раз предлагаешь наделить разным значением в зависимости от контекста.

Ну так-то ты прав

Твой вариант?

let. Или, может, то, что они там выдумали для лямбд

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

let.

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

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

Или, может, то, что они там выдумали для лямбд

В смысле?

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

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

let (x, y) = (5, 6) // x == 5, y == 6
let &z = &8; // z == 8
let *a = *b; // a == b

С этой точки зрения - логично. Что-то не так?

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

Что-то не так?

Может всё и так, но ведь приведённые примеры, сами по себе, ценности не несут. Вместо let &z = &8; можно (и нужно) написать let z = 8;, то есть проще запретить такие конструкции, чем усложнять их разбор. А если вводить их только ради матчинга, то и принципиальной разницы с ref, на мой взгляд, нет.

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

приведённые примеры, сами по себе, ценности не несут.

Я их не ради ценности приводил. Я через них объяснял логику паттерн-матчинга, как я её понимаю.

проще запретить такие конструкции, чем усложнять их разбор

С чего ему усложниться?

А если вводить их только ради матчинга

Кого вводить? Где я предлагал что-то вводить? Я предлагал заменить ref на * в паттерн-матчинге.

принципиальной разницы с ref, на мой взгляд, нет.

Есть. Консистентность с остальным языком и отсутствие необходимости в ключевом слове ref.

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

Я их не ради ценности приводил. Я через них объяснял логику паттерн-матчинга, как я её понимаю.

Это понятно. Вот только сейчас в следующей конструкции нет смысла

let *a = *b;
И ref так использовать нельзя, a ты предлагаешь её разрешить. Вот тебе маленькое, но усложнение.

Лично меня устроили бы оба варианта, хотя с непривычки такие вот использование разыменования и кажется «необычным»/неуместным.

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

И ref так использовать нельзя

С чего бы это?

с непривычки такие вот использование разыменования и кажется «необычным»/неуместным

Использование ref кажется нелогичным/неконсистентным даже с привычкой.

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

С чего бы это?

С того. Где там ref в обеих частях выражения?

Использование ref кажется нелогичным/неконсистентным даже с привычкой.

Ну кому как - мне пофиг.

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

Где там ref в обеих частях выражения?

Там же, где и логика тех, кто придумывал синтаксис ref-паттернов. Но если ты имел в виду это - ничего разрешать не надо и никакого усложнения там нет, тупая замена ref на * в парсере паттерн-матчинга.

Ну кому как - мне пофиг.

Ты просто не умеешь в логику паттерн-матчинга. Вон, посонам было не пофиг, но пришёл педиковатого вида грек, сказал «Некогда пилить нормальный синтаксис, надо быстрее в релиз!» и всех обломал. Собственно, вся суть разработки раста.

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

Ты просто не умеешь в логику паттерн-матчинга

Это Грейдон не умеет.

пришёл педиковатого вида грек

И сказал грек: «As you can see, it began with a proposal (by me, in fact) to use *T as the pattern syntax. Graydon has some (quite reasonable) objections here».

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

Это Грейдон не умеет.

Graydon Hoare> written-the-same-way pattern *P. Which is ... mathematically tidy

Graydon Hoare> Somehow no matter how many times I read it, when I see: let *x = foo; I expect this means that foo is a pointer and x is bound to the pointee.

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

И сказал грек

Зачем же людям так троллинг обламывать?

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

ref или *, вот в чём вопрос. Что благородней: терпеть наследье сишки, или восстать против Хоара и покончить с ней?

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

никакого усложнения там нет, тупая замена ref на * в парсере паттерн-матчинга.

Да, ты прав.

Собственно, вся суть разработки раста.

Так ты потроллить пришёл или что? В расте, как и везде, хватает кривоватых моментов, конечно. Но и их понять можно - бесконечно тянуть с релизом 1.0 нельзя. В свифте вон повыбрасывали операторы инкремента/декремента «после релиза» и не парились, но раст с такими решениями точно не выживет.

Да и в обсуждении видно, что с mut всё не так гладко получается.

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

Так ты потроллить пришёл или что?

А что, в срачи про синтаксис ЯП можно приходить за другим?

В расте ... хватает кривоватых моментов

ЧТД.

с mut всё не так гладко получается

Это у курильщиков сишников.

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

Причём Java вариант ещё и тормознутее.

Насколько тормознутее, как проверял?

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

filter(| &(_, v) | *v )

А что это за звездочка? А вот этот амперсанд, чтобы передало Entry<String,bool> по ссылке без копирования?

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

filter в данном случае принимает замыкание с типом FnMut(&(&String,&bool))->bool. То есть пара ключ/значение всегда передаются по ссылка, не зависимо от того что написано в параметре замыкания. Амперсанд в параметре деструктурирует ссылку и позволять сделать паттерн-матчинг с её содержимым.

Все эти строки делают одно и то же:

filter(|kv| *kv.1) // точка автоматически дереференсит ссылку
filter(|&kv| *kv.1) 
filter(|&(_,v)| *v)
filter(|&(_,&v)| v)

red75prim ★★★
()

Подскажите, а с си-биндингами и тредами в расте все в порядке? А то может зря учу. Смогу я в расте создать пару тредов и в каждом из них вызывать сишные либы? (при условии, что последние thread-safe, естественно)

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

filter(|&(_,v)| *v)

Получается здесь «деструктурирует ссылку» на пару ключ/значение, но т.к. у нас &bool, то нам нужно еще раз «деструктуировать ссылку» и делается это с помощью *v?

filter(|&(_,&v)| v)

Ну а тут &bool деструктуируем амперсандом сразу.

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

Да, без особых проблем. В cargo.toml добавить

[dependencies]
libc = "0.2"

Нужные функции объявляются как-то так

extern crate libc;
use libc::*;

#[link(name="mylib")]
extern "system" {
    pub fn my_func(param1: *const c_char, param2: c_int, param3: *mut *mut c_void) -> c_int;
}

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

Как вызывать сишные функции я уже прочитал. Собственно, эта легкость и подкупила начать курить раст. Интересно именно спаривание их с тредами. Не будет ли реализация тредов в расте как-то мешать пользоваться сишными либами (например, в го сишка подключается через тредпул (ЕМНИП), в питоне глобальный лок. Вдруг и в расте какая-нибудь хрень будет мешать)

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

Да и да. Звёздочка получает значение по ссылке, но деструктурированием это не называют. *v обычно называют разыменованием v. То же самое что и в С.

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

https://doc.rust-lang.org/book/patterns.html#destructuring

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

Собственно Rust и позиционируется как высокоуровневый C. Так что мешаться ничего не будет. Треды там нативные, сборки мусора нет.

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

Это радует. В планах переписать прикладную часть одного поделия на rust, со всеми его свистелками. Затем экспортировать это дело в сишные функции и использовать эти функции для создания красивого биндинга к lua

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

Так это наоборот получается? Rust библиотека вызывается из LUA? Я этим не занимался, так что точно не скажу. Но такой вариант сложнее, надо как-то инициализировать stdlib или обходиться без неё.

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

Если rust умеет выдавать so или a, которые можно подключить к сишному проекту, и тупо вызывать экспортированные функции, то проблем возникнуть не должно, по идее.

А что там за дела с stdlib? Почему ее нельзя?

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

Подробностей не знаю. Что-то связанное с инициализацией thread local storage.

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