Это копия, сохраненная 21 августа 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
ИТТ мы можем объяснить базовые и продвинутые концепции языка, и
программирования в целом, поможем вкатывающимся, подскажем что
выбрать для веба, игр или спасибо абу блокчейна.
https://www.rust-lang.org
> Пачиму helloworld весит как моя мамка?!1й
https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html
Читать
Оф. книга, она же растбук
https://doc.rust-lang.org/book/
https://rustbyexample.com/
Очень хорошая книга, отлично зайдет после растбука:
http://shop.oreilly.com/product/0636920040385.do
Упражнения
https://exercism.io/tracks/rust
https://github.com/crazymykl/rust-koans
Писать
IDE
https://areweideyet.com/
Вебня
http://www.arewewebyet.org/
Игры
http://arewegameyet.com/
Etc
https://wiki.mozilla.org/Areweyet
Список интересных проектов
https://github.com/rust-unofficial/awesome-rust
Новости
Компиляция всего, что произошло за неделю
Иногда постят вакансии
https://this-week-in-rust.org/
Сколько вешать в лайках
https://github.com/trending/rust
Оп рекомендует:
https://www.amethyst.rs/
https://github.com/TatriX/dvach
>Programming Rust почитай или просто задавай конкретные вопросы или приводи примеры кода.
Двачую за Programming Rust. Rust book говно какое-то: воды много, по делу мало, некоторой инфы вообще нет.
Ура, растопидоры запилили трхед и не будут срать в других
Не завидуй, маня.
В отличии от тебя, растопидоры знают более одного языка и скорее всего в них входят C и C++. Ты же не знаешь ни одного, студент мамкин.
>Memory is usually managed with garbage collection, but specific objects may be finalized immediately when they go out of scope
>Functions marked @safe are checked at compile time to ensure that they do not use any features that could result in corruption of memory, such as pointer arithmetic and unchecked casts, and any other functions called must also be marked as @safe or @trusted. Functions can be marked @trusted for the cases where the compiler cannot distinguish between safe use of a feature that is disabled in SafeD and a potential case of memory corruption.
этакая джява из мира с++?
Мудрость глаголишь.
Всё просто: у Торвальдса лучше всего стоял, когда си были также прогрессивны, как сейчас раст. Что может быть прекраснее поиска потенциального нулевого указателя в очередном коммите? Только внезапно обнаружить гонку при работе с памятью, через которую знающие люди имеют ядро во все щели уже лет 10 Dirty COW , ага
Такое-то ностальжи, такой-то адреналин, возможны только с сями.
Ну, расту ещё расти и расти, за 9 то надо что-то уже и придумать.
Сейчас бы учитывать мнение создателя ОС, в которой больше всего CVE находят в год.
Иди нахуй :)
Это очевидный пиздеж. Зачем ты так?
ну в твоей laba1 не используется, допустим. а хотел-то что сказать?
>Хотя бы потому что в отличии от Ди на расте есть блокчейнопараши, которые закроются, когда доедят деньги инвесторов
ftfy
Всегда можно будет уйти работать в Мозиллу но только если ты трансгендер-мусульманин, разумеется!
DEVS RUST!
Первое напишет, но не переведет строку, второе не скомпилится, третье перевдет каретку на новую строку после написания.
>Разработка Quantum CSS началась, чтобы повысить производительность. Улучшение безопасности — просто удачный побочный эффект.
>вся статья про количество багов и сколько этих багов самим существованием кода на Rust было закрыто. ну и какие-то васянские замеры в каментах.
так есть все-таки более или менее близкий к правде бенчмарк на какие-то параллелируемые алгоритмы на системных языках?
НИНУЖЕН РАСТ!!!! НИНУЖЕН Я СКАЗАЛ!!!! НУ ЧТО ЖЕ ВЫ НИ ПАНИМАЕТЕ ТО, ЧТО НИНУЖЕН!!!!!
https://blog.cloudflare.com/boringtun-userspace-wireguard-rust/
Что cloudflare, что dropbox основной код пишут на go, а на rust всякие latency-critical вещи или байтоебские.
Rust - также классный язык общего назначения, так что было бы круто, если бы всё на нем писали.
>>371865
Плюсоговно вообще не рассматриваю, желаю ему, чтобы оно поскорее сдохло.
Я только вкатываюсь в раст и вот только навскидку:
- В плюсах есть 5 конструкторов + 3 оператора присваивания. Некоторые из них имеют неявное преобразование аргументов, некоторые - нет. Все это говно надо держать в голове. Что есть в расте? А нихуя нет, просто вообще нет конструкторов. Можно сделать статический метод new, если хочешь. А можно и не делать.
- В плюсах есть 5 видов ссылок, lvalue, rvalue, xvalue и еще два, забыл их. Столько типов ссылок надо для разруливания тупорылого легасного приведения между разными ссылками в разных ситуациях. Подробнее здесь - https://en.cppreference.com/w/cpp/language/value_category . (Алсо после появления мув-семантики появилось 100500 статей, чтобы охуевшие бедолаги таки поняли это говно, что как бы намекает на качество дизайна языка).
В расте же ссылка либо mutable, либо шаренная, либо владеющая.
Просто выкидываем говно и получаем простую конфетку, которую легко изучать.
ну ебать
раст писался на плюсовом, в том числе, опыте нескольких десятков лет разработки тонн говна и адской боли от получившихся результатов. это как джяву упрекать в том, что она не дотнет
Я никого не упрекаю, просто агитирую за все хорошее против всего неудобного. С++ - легаси, Rust - не легаси, вот пару моментов "почему это так"
В C++ нормальные гибкие duck typed темплейты, Rust - безальтернативная тайпклассопараша.
Поэтому, к сожалению, Rust хуйня.
10 лет пытаются внедрить концепты(которые по сути тайпклассы), потому что от SFINAE и сообщений компилятора тянет блевать даже фанатов александреску. А rust с тайпклассами из коробки - это хуйня, да
>концепты(которые по сути тайпклассы)
Это не так.
У тайпклассов есть свои преимущества, но перед ООП с виртуальными методами и т. п. Но вот против мощи темплейтов в расте ничего нет.
Продемонстрируй эту самую мощь темплейтов и то, какие концепты не тайпклассы.
>так есть все-таки более или менее близкий к правде бенчмарк на какие-то параллелируемые алгоритмы на системных языках?
А что ты ожидаешь увидеть? Везде те же самые потоки на одних и тех же ОС и с теми же самыми мьютексами. В расте придется Arc поклонировать 16 раз, чтобы компилятор не ругался (но в зависимости от подхода то же самое нужно будет сделать и на плюсах). Смотри однопоточные тесты, дели на N, увидишь +\- точные цифры.
Да, я. Есть что по делу сказать?
>>371864
> Что cloudflare, что dropbox основной код пишут на go
Пока пишут. Вон один проект уже решили начать писать на расте, дальше - больше.
> latency-critical вещи или байтоебские
А у них (конкретно дропбокс и клауд) есть НЕ "latency-critical вещи или байтоебские" вещи (кроме фронтенда, офк)?
Кстати, этот впн таки не просто так, а для публичного сервиса: https://blog.cloudflare.com/1111-warp-better-vpn/
Да, поганая статья (всмысле того, как построена). Мне кажется, что мамзель не очень понимает как писать, или она не очень в теме что и зачем переписывалось на расте. Меня зацепила эта фраза: "By 2017, Mozilla had made two previous attempts to parallelize the style system using C++. Both had failed". Выглядит так, что стали переписывать потому что параллелить хуиту такого размера и сложности, как браузерный движок, было КРАЙНЕ сложно на крестах, и решили в итоге взять более строгий язык, не уступающий в скорости, "системный". Просто по поводу чистой скорости на один поток >>372691 правильно написал. Тут может быть выигрыш только за счет строгости самого языка и вытекающих отсюда оптимизаций.
https://github.com/rust-lang/rust/search?p=1&q=madoka&unscoped_q=madoka
>Но вот против мощи темплейтов в расте ничего нет.
А что есть у C++ против мощи макросов раста?
Почему на С++ с его мощными темплейтами невозможны такие вещи, как serde или pest?
У растодаунов королева-матка своя?
Я?..
Дочитал растбук до енумов. Всё круто. Проблем с концепцией владения вроде не возникло. Довольно простые правила, довольно логичные. Наверное просто мой мозг не засран концепциями C и C++. Хотя возможно это только верхушка айсберга.
Начинает напрягать вербозность растбука. Думаю перекатиться на rust by example. Стоит ли?
> Довольно простые правила, довольно логичные.
Ну, после NLL основная претензия к борроу чекеру это неудобства при работе со структурами. Вот тут поясняется подробней: http://smallcultfollowing.com/babysteps/blog/2018/11/01/after-nll-interprocedural-conflicts/
Что первое, что второе дрисня та еще. Читай лучше Programming Rust. Написали чуваки из language team
Зачем тебе вообще сдался раст? Не лучше ли улучшить свои навыки для шкалапидора?
Где тебе пригодится раст? Задумайся.
Я думаю, раст я буду использовать в вебе.
Потому что быстро и избавляет (насильно) от ошибок программиста. Плюс конкурренси, удобный тестинг, пара гендеров в кармане и тд.
1280x720, 1:50
К сожалению у меня нет контента по Расту.
Да и писать сейчас приходиться не на нём.
Но ты всё равно не умирай.
nth prime c++ - https://gcc.godbolt.org/z/5o11_8
nth prime c++ constexpr - https://gcc.godbolt.org/z/0jWK7p
Годно, базара ноль.
НО КАК ЖЕ ХОЧЕТСЯ ТЯНОЧКУ НОРМАЛЬНЫЙ CONST FN
А как в Rust с GUI дела обстоят? Я знаю про https://areweguiyet.com/ мне интересны ваши личные впечатления
> tui-rs is a Rust library to build rich terminal user interfaces and dashboards.
Это, конечно, не гуй, но выглядит интересно. А какие юзкейсы? Что-то я не припомню, что-бы в последнее время у кого-то были дашборды в терминале.
мимо другой анон
Ты просто виндузятник наверное. А консолечка очень популярна среди 1% от 1% всех линуксоидов.
Я прыщеблядь. Люблю пердолиться с консолькой, но ни разу не видел дашбордов в терминале. Или это что-то для петпроджектов?
Эх, хорошо бы что-то новое в вебе, но ТЕБЕ. ВСЕ. РАВНО. НУЖЕН. ДЖЭЭС. СУКА. Один хуй нужны биндинги к DOMу и всей хуйне, предоставляемой браузером. Хотя можно попытаться сделать фронт на yew, да.
Подожди, я тебе говорю просто факт: чтобы из WASM работать с DOMом, вообще с внешним миром, тебе нужны биндинги на JS. Да, часть кода сгенерируется (в том же yew тебе вряд ли понадобится JS для hello world), но JS все равно остается. Если хочешь опровергнуть, то покажи как без JS загрузить WASM модуль, как модифицировать DOM.
А свое
> Открой для себя мир kitlinjs, scalajs, tvoyamamkajs
можешь себе в задницу засунуть. А потом узнать, что это хуита, просто компилирующаяся в JS, а не WASM. И да, там тоже есть JS, внезапно, не так ли?
>компилирующаяся в JS
А что в этом плохого? Конпелируемые языки конпеляются, грубо говоря, в ASM, писать на котором та ещё мука.
Ничего особо плохого, наверно (кроме того что джс медленное говно, но оставим это в стороне). Но сравнивать Rust, который компилируется в WASM и Scala, которая в JS, немного некорректно. На что я и указал.
Да, есть Emscripten, который компилит в JS, но это все же немного другое опять же. Костыль для тех бразуеров, где нет поддержки WASM, и приходится LLVM в JS компилить, а не в WASM.
Мои навыки шкалапидора улучшаются параллельно.
Раст просто интересен, работу искать на нём не планирую.
Ты тупой да? На беке можно использовать что угодно, хоть асм. Ты такую сейчас неревантную хуйню сморозил.
Угу, так и есть. Я допускаю, что изначально все таки речь не шла о фронта, но вот фраза
> Я думаю, раст я буду использовать в вебе.
сделала меня думать про фронт и последующие несколько сообщений были ЯВНО про фронт.
Вообще, не смотря на то, что я не люблю JS по множеству причин, сложно отрицать что ему сейчас замен нет. Поэтому раст видится как только язык для всяких числодробительных модулей типа криптографии.
ЛОЛ, да у него же синдром утенка + Когда всю жизнь пишешь на одном языке, ясен хуй он для тебя как родной
лексические макросы например,
#define, #ifdef, #endif, #undef,
#pragma,
потом че еще, ну там крутой современный подход к созданию модульных приложенией:
#include "linux.h" // вот так типо
оно там копирует и линкует потом, вообще топчик
Можно функции свои делать типо
#define sum(x, y) ((x) + (y))
там еще можно имя переменной подставлять типо #y или как то так
elm?
Он где-то говорил про Раст что-то в духе "говно, конечно, но гораздо лучше, чем то, что пытались делать раньше". Там что, можно считать, что ему понравилось.
Ну и шо, в расте можно для std трейты самому пилить?
че-то я в списке методов String::from не вижу <T: Display>. схуяли ты решил, что оно должно заработать?
Да хуй знает. Чем тогда отличается реализация to_string от Display и от String::from, нахуй столько вариаций?
String::from - это конвертер
Display - это для форматированного представления в условную консольку или поток ошибок
это не совсем одно и то же, хотя под капотом однохуйственно превращается из T в String. это как шаблоны адаптер и декторатор смешивать. потому, что под капотом запускают целевой метод интерфейса
Ок, допустим, результат String::from и форматирования YobaStruct может отличаться. А to_string? Вот я пишу структуру, почему нужно для преобразования её в строку отдать предпочтение String::from, а не to_string?
а почему нужно отдавать предпочтение? я, конечно, нубас еще, но подобных догм не встречал
Да я сам нубас, поэтому спрашиваю как тут ПРИНЯТО. Ну вот если я запилю и to_string, и String::from, которые будут работать одинаково, нахрена их две штуки тогда? Но зачем-то же сделали возможность преобразовать структуру в строку двумя путями, я вот и спрашиваю, зачем. Ну и, собственно, не понятно тогда от остальных типов чего ожидать для этого: to_string или String::from. Выходит, либо для каких-то случаев один из них предпочтительнее, либо просто две нахуй не нужных одинаковых сущности зачем-то запилили.
Алсо, лапша вроде xyu.iter().enumerate().map().govno().mocha().nebo().allah().flatten().collect() приемлема в коде или лучше разбивать на куски?
>лапша
А в чем тут лапша, можешь объяснить?
>разбивать на куски?
А как именно ты бы это разбил на куски? xyu_iterated = xyu.iter(); xyu_enumerated = xyu_iterated.enumerate(), лол?
Builder на любом языке превращается в цепочку из подобных какашек. пример так се
useless();
}
fn useless() {
let vector = vec!(3, 2, 1, 1 / 0);
}
почему канпелятор не настолько умный шобы выпилить аллокацию вектора? в расте нет многообещанной плюсами "плати за то, что используешь"? (я хз, работает ли оно там или нет)
и второе, для того, чтобы использовать условный lazy для элементов, мне обязательно пердолиться функторами/замыканиями? чтобы, например, сделать такое:
vec!(3, 2, 1, 1 / 0).len();
Видать именно поэтому в rust'е все имена убого сокращены: "vec" "fn" "str" "mut" "iter" "into_iter" "sleep_ms"...
А еще убогость в сочетании camel case и сишных hui_pizda
Кстати, актуальный вопрос. Растоманы, к вам не лезут на Гитхабе с заявлениями, что нельзя называть пользователя "he", надо добавить больше CoCа и т.д.? У меня сложилось такое впечатление, что англоязычное сообщество Раста в этом плане одно из самых неадекватных.
>почему канпелятор не настолько умный шобы выпилить аллокацию вектора?
Тебе ж будет ворнинг о неиспользуемом значении, что еще надо-то?
http://piston-tutorial.logdown.com/
только работающий. Приведённый устарел настолько, что интерфейс библиотеки уже совсем другой, тамошний код не работает нихуя.
докладываю, на линухе эта еболда завелась прям без бубнов. проде бы пакеты установлены те же, что и на шиндошсе
лучи поноса пользователям электрона.
спасибо хоть телега пишет свою морду на сях. Единственное пользовательское приложение из 2019 года которое не жрёт оперативку как не в себя
И которое работает по-настоящему отзывчиво. Надеюсь в будущем gui будут писать на расте, который будет тем qt, который мы всегда хотели
Печально.
// Турист с визитом из ГоЛанга
> Надеюсь в будущем gui будут писать на расте, который б
Угу, сейчас. Все обоссываются от счастья от WASM-а. Комитетов по продвижению насобирали больше чем было при Хрущеве, а толку ноль.
Как была разработка и компиляция под WASM процессом, напоминающим секс на ходулях, так и осталась.
>WASM
Я ващет не погромист, я клавиатуру на помойке нашёл,
но у меня вопрос:
разве васм это не результат компиляции?
Если хочешь писать морду на васме - надо писать её на цивилизованном языке, вроде плюсов, и потом компилировать в васм.
Но, блядь, для десктопной ебалы (типа скайпа или слака, которые блядь просто абузят электрон, сука, блядь, почему чат подвешивает машину в 2019, ёбанарот), проще её допилить до вменяемого состояния и скомпилировать сразу в асм, выкинув в мусорку весь движок хрома и плюнув ему в след.
Разве я не прав?
@
ПАКУЕШЬ В ЕЛЕКТРОН
нахуя ты это сюда принес, додик?
Никогда я не понимал мотивации мудаквижн. Они же натуральные уебаны.
когого хуя, спрашивается?
вангую, что Lines::next()::to_lowercase() возвращает нечто, у которого contains() имеет чутка другую сигнатуру?
Ну и что можно сделать на вашем расте? Говно язык без тулинга.
ты вместо кложуры передал результат выполнения метода. Засунь метод, который после столбов || в фигурные скобки:
| a, b | {magic(a, b)} - кложура
| a, b | magic(a, b) - хуйня какая-то
OCHE TOLSTO
>говно без тулинга
Ты скажи, на каком языке пишешь и что ты хочешь от тулинга, а я тебя аргументированно обоссу
Не корми, это какой-нибудь мамкин криптоброкер. Открыл для себя tensorflow и pandas и думает что выиграл в программировании.
>не корми
Судя по активности треда, раст либо идеальный и ни у кого не возникает ни одного вопроса при его использовании, либо он никому не нужен и в следующем треде надо позаимствовать шапку у D треда.
Так что я лучше осознанно покормлю
>Судя по активности треда, раст либо идеальный и ни у кого не возникает ни одного вопроса при его использовании, либо он никому не нужен
..., либо он никому не нужен на борде для девочек-анимешниц, и серьёзные разговоры про раст нужно искать тут:
https://www.reddit.com/r/rust
https://www.reddit.com/r/rust_gamedev
https://stackoverflow.com/questions/tagged/rust
https://www.rust-lang.org/community
Ну то есть, реально, вариантов только три, и совершенное не ясно, какой из них имеет место быть в действительности.
Растоёбы утверждают, что в Расте корректность управления памятью чекается статически. Это означает две с половиной вещи:
1. Должно быть какое-то ограничение, иначе статический чекер просто не будет работать.
2. Должен быть способ обойти это ограничение, иначе некоторые корректные программы на Расте будет просто невозможно написать.
2.5 Этот способ должен быть не тайным знанием, тонким слоем размазанным по кодобазе, а сосредоточен в каком-то одном месте с большой красной надписью "ВНИМАНИЕ В ЭТОМ МЕСТЕ ВЫ ОТКЛЮЧАЕТЕ ВСЮ АВТОМАТИЧЕСКУЮ БЕЗОПАСНОСТЬ И ПЕРЕХОДИТЕ НА ТЁМНУЮ СТОРОНУ ([x] - Да я понимаю что делаю и согласен что все дальнейшие сегфолты - моя личная вина)". Обращение к этому место должно происходить крайне редко, потому что язык должен быть спроектирован так, чтобы всё работало на автомате, но в растокомьюнити должно быть очень четкое понимание, когда именно этим следует пользоваться.
Чтобы было понятнее, о чём я говорю, приведу пример для Агды. Агда гарантирует, что любая тайпчекнутая программа, написанная на ней, гарантированно завершается. Но это, очевидно, нельзя проверить для произвольной тьюринг-полной программы, а Агда - тьюринг-полный язык программирования. Поэтому в Агде есть специальная прагма TERMINATING, которая отключает termination checking в том месте, где это не может быть проверено автоматически, но программист гарантирует, что там всё в порядке. Как правило, это какие-то хорошо отлаженные библиотечные функции (не буду пиздеть, сам я не агдаёб, просто видел у них), т.е. в 99.999% в пользовательской программе эта прагма не используется, но агдаёбы очень хорошо понимают, где и зачем это надо применять.
Прошу фанбоев не постить методички про ownership и livetimes (с тем же успехом я мог бы почитать высеры крестоблядков про их смартпоинтеры), а умных растоёбов указать, какие именно ограничения использует Rust и привести пример программы, когда растовский чекер не способен понять, что память можно освобождать и вынуждает писать программу, которая будет хавать память бесконечно, а также тот самый способ отключить проверку. Пример должен быть где-то внутри стандартной библиотеки Раста, что-то мне подсказывает.
Растоёбы утверждают, что в Расте корректность управления памятью чекается статически. Это означает две с половиной вещи:
1. Должно быть какое-то ограничение, иначе статический чекер просто не будет работать.
2. Должен быть способ обойти это ограничение, иначе некоторые корректные программы на Расте будет просто невозможно написать.
2.5 Этот способ должен быть не тайным знанием, тонким слоем размазанным по кодобазе, а сосредоточен в каком-то одном месте с большой красной надписью "ВНИМАНИЕ В ЭТОМ МЕСТЕ ВЫ ОТКЛЮЧАЕТЕ ВСЮ АВТОМАТИЧЕСКУЮ БЕЗОПАСНОСТЬ И ПЕРЕХОДИТЕ НА ТЁМНУЮ СТОРОНУ ([x] - Да я понимаю что делаю и согласен что все дальнейшие сегфолты - моя личная вина)". Обращение к этому место должно происходить крайне редко, потому что язык должен быть спроектирован так, чтобы всё работало на автомате, но в растокомьюнити должно быть очень четкое понимание, когда именно этим следует пользоваться.
Чтобы было понятнее, о чём я говорю, приведу пример для Агды. Агда гарантирует, что любая тайпчекнутая программа, написанная на ней, гарантированно завершается. Но это, очевидно, нельзя проверить для произвольной тьюринг-полной программы, а Агда - тьюринг-полный язык программирования. Поэтому в Агде есть специальная прагма TERMINATING, которая отключает termination checking в том месте, где это не может быть проверено автоматически, но программист гарантирует, что там всё в порядке. Как правило, это какие-то хорошо отлаженные библиотечные функции (не буду пиздеть, сам я не агдаёб, просто видел у них), т.е. в 99.999% в пользовательской программе эта прагма не используется, но агдаёбы очень хорошо понимают, где и зачем это надо применять.
Прошу фанбоев не постить методички про ownership и livetimes (с тем же успехом я мог бы почитать высеры крестоблядков про их смартпоинтеры), а умных растоёбов указать, какие именно ограничения использует Rust и привести пример программы, когда растовский чекер не способен понять, что память можно освобождать и вынуждает писать программу, которая будет хавать память бесконечно, а также тот самый способ отключить проверку. Пример должен быть где-то внутри стандартной библиотеки Раста, что-то мне подсказывает.
>Пример должен быть где-то внутри стандартной библиотеки Раста, что-то мне подсказывает.
В смысле пример отключения чекера, а не пример, который хавает память бесконечно)) ну вы поняли.
> иначе некоторые корректные программы на Расте будет просто невозможно написать.
Там всё возможно написать. Обычно unsafe (а именно эта штука и отключает borrow checker вместе с некоторыми другими проверками) используют ради пирформанса. Например можно использовать умный указатель Rc (или Arc для многопоточных приложений) [1] с подсчётом ссылок плюc Cell (если внутри хранится значение, которое будешь полностью изменять внутри) или RefCell (если хранится ссылка или структура, которую полностью менять нет смысла) [2]. Но это всё будет медленней, чем работать со ссылкой напрямую, если ты точно знаешь время её жизни и можешь вручную её уничтожить. Пример: linked list, который можно сделать как через (A)Rc так и напрямую через unsafe (вот тут разжевывается подробно с кучей как safe, так и unsafe примеров: [3]).
Проще говоря корректные программы всегда можно написать на расте, просто часть этих проверок будет пересена (но только если ты сам это захочешь, автоматически в расте ничего не делается) из компил-тайма в рантайм, что потенциально сделает программу медленней.
> Этот способ должен быть не тайным знанием, тонким слоем размазанным по кодобазе, а сосредоточен в каком-то одном месте с большой красной надписью "ВНИМАНИЕ В ЭТОМ МЕСТЕ ВЫ ОТКЛЮЧАЕТЕ ВСЮ АВТОМАТИЧЕСКУЮ БЕЗОПАСНОСТЬ И ПЕРЕХОДИТЕ НА ТЁМНУЮ СТОРОНУ
Целые книги по unsafe расту пишут (причём сами разработчики): [4].
[1]: https://doc.rust-lang.org/std/rc/index.html
[2]: https://doc.rust-lang.org/std/cell/index.html
[3]: https://rust-unofficial.github.io/too-many-lists/index.html
[4]: https://doc.rust-lang.org/nomicon/README.html
Азы ансейфа описываются в каждом мануале по расту, для глубокого понимания есть куча книг.
Если ты не в курсе про него значит ты даже вики-статью про Раст не осилил, и объяснять тебе что-то потеря времени.
>Там всё возможно написать. Обычно unsafe (а именно эта штука и отключает borrow checker вместе с некоторыми другими проверками) используют ради пирформанса.
Не-не-не. Должен быть пример не ради пирформанса, а именно пример, в котором чекер принципиально не способен работать. Т.е. пример, в котором чекер будет вынуждать тебя не освобождать память вплоть до завершения программы и потенциально хвавать память бесконечно, при том, что сама программа корректная и может уложиться в конечную память.
Когда мы говорим о перформансе, мы утверждаем, что можем освобождать память пусть не оптимально, но существует некая аппроксимация, позволяющая гарантированно это сделать за конечное число шагов. Так вот, я утверждаю, что такой аппроксимации не существует. Ведь если бы она была, то проблема остановки была бы разрешима, пусть даже за хулион шагов, что не применимо на практике, но теоретически, она бы была решаемой. А цимес в том, что она даже теоретически неразрешима. Ну или я что-то не понимаю в управлении памятью, тогда опровергните мою гипотезу.
>Целые книги по unsafe расту пишут
Спасибо, прочитаю.
> а именно пример, в котором чекер принципиально не способен работать.
Я ж тебе говорю, в расте есть возможность переносить чекер в рантайм. Единственное место где подсчёт ссылок работать не будет - если структура ссылается на саму себя. Всё.
ну так два метода с одинаковой сигнатурой замыкания. вопрос был про то, что в одном случае str => str работает, в другом выдает ошибку компиляции
>>388796
.filter(|line| line.contains(query))
это ведь канает
>>388543
после решарперовского интеллисенса на русте совсем грустно гуглить документацию. посеба
>Ну или я что-то не понимаю в управлении памятью, тогда опровергните мою гипотезу.
Ради пирфоманса освобождать память не нужно вообще. Нужно выделять паять большими кусками аля 512метров, гиг, джва гига и уже поверх этих кусков писать свой кастомный аллокатор/переиспользовать объекты.
Тогда уж лучше свой собственный сборщик мусора писать, иначе пирформанс может падать из-за постоянных аллокаций при создании объекта и деаллокаций при уничтожении, а специализированный GC может маленькие объекты создавать в специальном месте не выполняя аллокации вообще, а освобождать объекты в отдельном треде.
Уничтожение объекта так же происходить не должно, вместо этого ссылка на него/индекс массива в котором он лежит отправляется в стек "свободных объектов", откуда фабрика его потом пытается взять и повторно инициализировать конструктороподобным паблик методом.
ой блять
Перед тем, как заходить в этот тред, надо включать мозг. Те, кто этого не делают, будут посланы нахуй быстрее, чем они успеют сказать "не понял".
Полегче со словами, токсик. Иди проверь свои привилегии.
Кстати, мозилла закрывает IRC-чятик для всех своих продуктов, потому что там было слишком много харрасмента и их слишком сложно модерировать: https://blog.rust-lang.org/2019/04/26/Mozilla-IRC-Sunset-and-the-Rust-Channel.html
Этот токсичный тред тоже не мешало бы закрыть (ну или хотя бы поставить несколько модераторов с phd по гендерным наукам). Язык программирования rust заслуживает большего.
А вы точно при рождении были афро-русской? Может вы были белой, и просто покрасили лицо в афро-русский цвет? В таком случае это называется блекфейс и это очень привилегированно и плохо.
> надо включать мозг
Если под этим ты понимаешь "знать рандомного хуесоса, сделавшего очередную хуйню", то у меня для тебя плохие новости...
С другой стороны, нахуй их сеть ненужна никогда была, есть же фринод.
Язык ради языка.
Я вообще пишу под гейось и ведро. Последний год наблюдаю за рустом, одни поделки уровня б, прикрываемые под инновационными словами development.
Максимум зачем он нужен, так это написать сортировочку пузырьком. Реальные решения уже давно реализованы и имеют 30к+ на гите.
Даже лень придумывать язвительный комментарий
https://github.com/cloudflare/boringtun
https://github.com/BurntSushi/ripgrep
https://www.wired.com/2016/03/epic-story-dropboxs-exodus-amazon-cloud-empire/
https://www.rust-lang.org/static/pdfs/Rust-npm-Whitepaper.pdf
https://www.rust-lang.org/static/pdfs/Rust-Chucklefish-Whitepaper.pdf
https://www.rust-lang.org/static/pdfs/Rust-Tilde-Whitepaper.pdf
https://hacks.mozilla.org/2019/02/rewriting-a-browser-component-in-rust/
https://www.reddit.com/r/rust/comments/bhtuah/production_deployment_of_rust_in_hft_system_at/
+ еще куча блокчейн и финтех стартапов, внутренние проекты многих контор (https://prev.rust-lang.org/en-US/friends.html). Короче, подотрись и иди назад в свой яблочный загон.
>одни поделки уровня б, прикрываемые под инновационными словами development.
Редхат, мозилла и парити расплакались и уползли обратно под шконку, прихватив с собой свои поделки, ведь мобильный программист Олег, занимающийся поддержкой "Копателя", поставил их на место.
>Но это, очевидно, нельзя проверить для произвольной тьюринг-полной программы, а Агда - тьюринг-полный язык программирования
Чистый Раст без unsafe (включая код стандартной библиотеки) не является Тьюринг-полным языком. Если не использовать рекурсию, то он вообще регулярный, т.е. сводится к конечному автомату, а если использовать, то бесконтекстный. Следовательно, проблема останова для рекурсивно-перечислимых языков к нему не применима. Ебать, мне наконец-то пригодились знания из книги по формальным грамматикам, спасибо Абу.
Из этого следует, что борроучекер не работает в случае, когда нам нужны возможности, выходящие за рамки контексто-свободных языков. Конкретно - когда нам нужно создавать объекты произвольного объёма и структуры. В таких случаях нужно создавать абстракции, которые позволяют свести работу с произвольными структурами к работе над конечным числом биндингов. Например, итератор по вектору - это структура, позволяющая коду работать с коллекциями неизвестного размера, но сама по себе состоит из в точности двух указателей, поэтому может спокойно анализироваться борроучекером.
>и привести пример программы, когда растовский чекер не способен понять, что память можно освобождать
Всё, что выделяется не на стеке, под ответственностью программиста или создателя либы. Если программист не определил деструктор, то будет утечка, если где-то скопировал указатель, но не сказал компилятору, то будет висячий указатель.
не понял
ОК, еще инстайты есть у тебя?
Ну ты можешь сделать поля своей структуры не публичными, тогда инстанс такой структуры не создать через фигурные скобочки, только через функцию.
В рамках одного модуля такой возможности нет.
В случае разных модулей, если у структуры есть непубличные поля, то инстанцировать её напрямую нельзя. Отсюда растут несколько соглашений:
1) Если инстанс можно создать без параметров, то это делается через трейт Default
2) Основной конструктор называют Foo::new
3) Часто доп. конструкторы называют Foo::with_bar
>3) Часто доп. конструкторы называют Foo::with_bar
Бля, я тут как раз читал одни сырцы и не мог понять такую конструкцию:
world
.create_entity()
.named("Plant")
.with(PlantTag)
.with(collider::Circle::new(0.8))
.with(mesh.clone())
.with(handle.clone())
.with(transform)
.build();
Я так понимаю всё что после имени это что-то типа ступенчатого конструктора?
Если интересно, это какое-то студенческое поделие на аметисте.
> Я так понимаю всё что после имени это что-то типа ступенчатого конструктора?
Это паттерн builder. Очень популярен в Java.
я не уверен, что у инстанса нужно указывать его "ссылочность". попробуй _ => { Err }.
или &_a => { Err } если я не прав
Ты ебанат? Ты бы ещё тупо на аметист ссылку скинул.
тележка имеет некоторую скорость V в некоторый момент времени t0. На тележку действует сила трения качения в продольной оси и сила трения скольжения перпендикулярно ей. Найти вектор скорости тележки в некоторый момент времени t1 = t0+dt.
Я вот схему захуярил - чёрный это скорость V (зелёный - neg(V), просто штоб было), красный - направление продольной оси тележки, её "перед". Поносно-жёлтый - это трение, трение качения маленькое, а трение скольжения большое.
У меня было решение на num через комплексные числа, но я пытаюсь перепилить на nalgebra, и по пути может оптимизировать, если есть что-то умнее.
Вот на num (self.friction_coll - продольное трение, self.friction_orth - поперечное, self.heading - угол между передом тележки и x axis):
fn calculate_velocity_after_friction(&self, vel: Complex<f64>, dt: f64) -> Complex<f64>{
let coll_f = -Complex::from_polar(&(self.friction_colldt),
&self.heading);
let orth_f = Complex::from_polar(&(self.friction_orthdt),
&(self.heading+(std::f64::consts::PI/2.0)));
let denom: f64 = coll_f.reorth_f.im - orth_f.recoll_f.im;
let mut a =
(coll_f.revel.im - vel.recoll_f.im)/denom;
let mut b =
- (orth_f.revel.im - vel.reorth_f.im)/denom;
if a > 0.0 {
a = -a;
}
if b > 0.0 {
b = -b
}
if a < -1.0 {
a += 1.0;
} else {
a = 0.0;
}
if b < -1.0 {
b += 1.0;
} else {
b = 0.0;
}
aorth_f + bcoll_f
}
тележка имеет некоторую скорость V в некоторый момент времени t0. На тележку действует сила трения качения в продольной оси и сила трения скольжения перпендикулярно ей. Найти вектор скорости тележки в некоторый момент времени t1 = t0+dt.
Я вот схему захуярил - чёрный это скорость V (зелёный - neg(V), просто штоб было), красный - направление продольной оси тележки, её "перед". Поносно-жёлтый - это трение, трение качения маленькое, а трение скольжения большое.
У меня было решение на num через комплексные числа, но я пытаюсь перепилить на nalgebra, и по пути может оптимизировать, если есть что-то умнее.
Вот на num (self.friction_coll - продольное трение, self.friction_orth - поперечное, self.heading - угол между передом тележки и x axis):
fn calculate_velocity_after_friction(&self, vel: Complex<f64>, dt: f64) -> Complex<f64>{
let coll_f = -Complex::from_polar(&(self.friction_colldt),
&self.heading);
let orth_f = Complex::from_polar(&(self.friction_orthdt),
&(self.heading+(std::f64::consts::PI/2.0)));
let denom: f64 = coll_f.reorth_f.im - orth_f.recoll_f.im;
let mut a =
(coll_f.revel.im - vel.recoll_f.im)/denom;
let mut b =
- (orth_f.revel.im - vel.reorth_f.im)/denom;
if a > 0.0 {
a = -a;
}
if b > 0.0 {
b = -b
}
if a < -1.0 {
a += 1.0;
} else {
a = 0.0;
}
if b < -1.0 {
b += 1.0;
} else {
b = 0.0;
}
aorth_f + bcoll_f
}
Код не понял и не вчитывался, линалом в расте не пользовался, но было дело в других языках. Мой совет -- делай так, как ты бы делал в школе на уроке физики.
У тебя есть начальное положение s0, начальная скорость v0 и уже посчитанные силы. Считаешь результирующую силу F, это ведь просто сумма всех векторов. Считаешь вектор ускорения как a = F/m. Интегрируешь самым простым методом Эйлера новую скорость (v = v0 + dt * a). То же с положением. Раз ты в физике -- не выходи за пределы домена физики.
Боюсь представить, как ты силы трения вычислял. Там же проекции брать надо, скалярные произведения делать, а у тебя в коде даже функции нормирования отдельной нет.
Алсо, можешь посмотреть https://youtu.be/LoTRzRFEk5I по теме
Я сам давно смотрел это видео, но обычно Кейси довольно доходчиво всё объясняет.
или после обосранного итт растбука Proramming стоит прочитать прям совсем по касательной, дабы освежить/улучшить понимание некоторых вещей?
>>393233
>Считаешь результирующую силу F, это ведь просто сумма всех векторов.
Ты простой такой, аж зубы сводит.
Подумай на досуге, что если по одному из измерений вычисленное изменение скорости за dt будет больше чем имеющаяся скорость? Тележка покатится в обратную сторону под действием силы трения? Норкоман?
>Боюсь представить, как ты силы трения вычислял. Там же проекции брать надо, скалярные произведения делать, а у тебя в коде даже функции нормирования отдельной нет.
Это и есть отдельная функция. Нахуя мне выносить нормирование куда-то ещё, если оно мне не нужно больше нигде? Понадобится - отрефакторю.
Короче, гуляй нахуй отсюда, профессор "код не читал, но осуждаю".
Я знаю кинематику получше тебя, осмелюсь предположить. Можешь засунуть свои школьные видео себе в жопу.
Спрашивал, есть ли более умный способ, чем разложить вектор на базис и вычислить поэлементную векторную сумму.
Вроде прикола с квейком, где они извлечение корня заменили умножением и сложением.
Нет, школофизики меня будут векторам учить.
>>393323
>код не читал, но осуждаю
Потому что твой говнокод трудно читать, делать мне на дваче нечего больше. Да и четыре условия у тебя в функции -- бранч предиктор охренеет и именно на нём твоя функция и тормозила бы. Если бы у тебя были нормальные функции для работы с векторами, ты бы сделал как-нибудь так:
orthPart = min(project_len(V, orth_f) - len(orth_f), 0) norm(orth_f)
collPart = min(project_len(V, coll_f) - len(coll_f), 0) norm(coll_f)
По мне, работать с голыми координатами, когда у тебя есть нормальная геометрическая интерпретация - неблагодарное дело. Без бранчей, кстати SIMD-зируется - вот тебе ещё и (минимум) трёхкратное увеличение производительности
И вот так при помощи одного вменяемого ответа ты превратился из прохожего мудака в уважаемого господина.
Хотя я уже вижу различия, при создании std::unique_ptr из другого unique_ptr, мы можем сделать borrow в С++, но когда созданный unique_ptr уничтожится - reborrow не произойдёт. Так что это не полное соответствие.
Крестушок
>при создании std::unique_ptr из другого unique_ptr, мы можем сделать borrow в С++,
Ты хотел сказать, мы обязаны сделать move? Причем здесь borrow?
Да, я чёто перепутал концепции. Блин, лучше не пытаться маппить это всё на уже известный мне С++, получается фигово.
Операционку написать.
Реализацию TCP/IP стека.
Любым байтоёбством заняться, которое тебе по душе.
Да ты сначала задачи порешай, после жса охуеешь, базарю. Я после питона охуеваю и пишу по 3 часа то, что на питоне за 10 минут наебенил бы.
Для начала растбук прочитай/прорешай.
Если не знаешь английский на достаточном уровне - не лезь, материалов на русском мало.
Для того чтобы броадкастить полученное сообщение всем подключенным клиентам, мне нужно где-то хранить всех подключенных клиентов, я использую HashMap с Arc и RwLock чтобы безопасно шарить его между тредами:
let mut clients = Arc::new(RwLock::new(HashMap::new()));
Далее, для каждого входящего соединения создаю новый тред:
for connection in server.filter_map(Result::ok) {
let mut connections = connections.clone();
thread::spawn(move || {
...
}
}
Внутри каждого треда я делаю accept подключения, получаю IP клиента, и разбиваю подключение на две части - приемник и отправщик (так сделано в крейте):
let client = connection.use_protocol("ws-test").accept().unwrap();
let ip = client.peer_addr().unwrap();
let (mut receiver, mut sink) = client.split().unwrap();
На этом этапе у меня есть sink, соответственно я могу заполнить мой HashMap для использования в дальнейшем:
connections.write().expect("RwLock is poisoned").insert(ip, sink);
Тут появляется первая проблема, т.к. происходит ownership transfer переменной sink в HashMap. Если передавать ссылку, то компилятор говорит что borrowed value does not live long enough, очевидно потому что HashMap находится за пределами треда, а значение которое я пытаюсь передать по ссылке умрет вместе с тредом. Это вызывает проблемы далее.
После этого, если сообщение на сервер пришло, я пытаюсь отправить его всем клиентам которые есть в connections вот таким образом:
for (_, client) in connections.read().expect("RwLock is poisoned").iter() {
client.send_message(&message);
}
Компилятор выбрасывает ошибку: `client` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Как я понял, client это не mutable reference, и из-за этого переменная cannot be borrowed as mutable.
Я пробовал поменять iter() на iter_mut(), но тогда возникает та же ошибка, но в другом месте (где вызывается iter_mut():
55 | for (_, client) in connections.read().expect("Posion").iter_mut() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
На этом моменте я зашел в тупик, не понятно что я делаю не так? Почему при попытке вызвать iter_mut() borrowing недоступен? Извиняюсь если очень тупой вопрос, учить язык я начал недавно.
Для того чтобы броадкастить полученное сообщение всем подключенным клиентам, мне нужно где-то хранить всех подключенных клиентов, я использую HashMap с Arc и RwLock чтобы безопасно шарить его между тредами:
let mut clients = Arc::new(RwLock::new(HashMap::new()));
Далее, для каждого входящего соединения создаю новый тред:
for connection in server.filter_map(Result::ok) {
let mut connections = connections.clone();
thread::spawn(move || {
...
}
}
Внутри каждого треда я делаю accept подключения, получаю IP клиента, и разбиваю подключение на две части - приемник и отправщик (так сделано в крейте):
let client = connection.use_protocol("ws-test").accept().unwrap();
let ip = client.peer_addr().unwrap();
let (mut receiver, mut sink) = client.split().unwrap();
На этом этапе у меня есть sink, соответственно я могу заполнить мой HashMap для использования в дальнейшем:
connections.write().expect("RwLock is poisoned").insert(ip, sink);
Тут появляется первая проблема, т.к. происходит ownership transfer переменной sink в HashMap. Если передавать ссылку, то компилятор говорит что borrowed value does not live long enough, очевидно потому что HashMap находится за пределами треда, а значение которое я пытаюсь передать по ссылке умрет вместе с тредом. Это вызывает проблемы далее.
После этого, если сообщение на сервер пришло, я пытаюсь отправить его всем клиентам которые есть в connections вот таким образом:
for (_, client) in connections.read().expect("RwLock is poisoned").iter() {
client.send_message(&message);
}
Компилятор выбрасывает ошибку: `client` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Как я понял, client это не mutable reference, и из-за этого переменная cannot be borrowed as mutable.
Я пробовал поменять iter() на iter_mut(), но тогда возникает та же ошибка, но в другом месте (где вызывается iter_mut():
55 | for (_, client) in connections.read().expect("Posion").iter_mut() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
На этом моменте я зашел в тупик, не понятно что я делаю не так? Почему при попытке вызвать iter_mut() borrowing недоступен? Извиняюсь если очень тупой вопрос, учить язык я начал недавно.
Сам спросил, сам ответил, и вопрос действительно глупый. Поменял connections.read() на connections.write() и все заработало. Я же правильно понял что read() не работал из-за того что это чтение, соответственно возвращается immutable reference, а функции send_message из моего кода нужен был &mut self?
>Любым байтоёбством заняться, которое тебе по душе
>байтоёбством
Маняфантазии подъехали. Впрочем, ничего удивительного в пидортреде не вижу. Раст как был для 0.5% задач создан, так его и используют. Больше он нигде и ненужен, особено впечатляют маняпроекты с версиями 0.0000012141412 с припиской build with rust. Тьфу блять, аж противно. Интересно, что зашкварней, писать такое говно на хуясте, писать бек на пхпдерьме или жрать говно вместе с жс? Оставляю на ваше усмотрение, инфантильные ублюдки.
Твои предложения? Сеплюхплюх?
Ты припёрся хуй пойми откуда специально, чтобы рассказать какое раст говно и какие мы инфантильные ублюдки?
Ебать пичот.
Ещё thread-safety можем.
Вот хочу я вектор расшарить - в чём проблема одолжить его треду, а ниже перехватывать попытки записи (но не чтения) в одолженное?
Зацени пример. Типа, посылаешь ты вектор в тжред, тжред из него чего-нить печатает, а тем временем в главном треде ты тоже чего-нить из него печатаешь.
Ну, а если типа прикрутить к объекту счётчик одалживаний, типа как монадой, и менять его при каждом новом одалживании. Кому не нужен - пусть уменьшает счётчик, если, внезапно, 0, то удаляем объект. Или это уже gc получится?
Arc/Mutex какое-то дно ебаное и оверкилл, когда нужно только чтение в потоках.
Arc + Mutex и есть счётчик отдалживания.
Я второй день учу раст, и я не понял - это ты что, создаёшь по отдельной копии на тред?
let mut physic_world = world.write_resource::<::resource::PhysicWorld>();
дженерик функцию я пойму, там func<T>(a: T), но что такое бле func::<T>()?
Я его ковыряю вторую неделю, но следить не слежу. Откуда твоя информация?
Я только слыхал что они в следующем релизе вроде как вулкан выкатывают.
Потому что каждый релиз "мы все нахуй переделали".
Сначала они поменяли мат. либу. Потом вроде как перепилили половину апи. И вот скоро опять перепилят с вулканом или че там будет.
А делать что-то на либе, которая каждый релиз ломает обратную совместимость мне совершенно не хочется. Я так уже с ggez поебался.
Хочется понять какие у них планы и когда ожидается стабилизация.
>Сначала они поменяли мат. либу.
То есть ты бы предпочёл чтобы они остались на ящике, который перестали поддерживать что ли? Ебать психопат.
>А делать что-то на либе, которая каждый релиз ломает обратную совместимость мне совершенно не хочется.
Добро пожаловать в мир early-софта, всё сырое и меняется, ищешь стабильности - пиздуй в ANSI C.
Нет, я за то чтобы они на главной повесили ссылку на план, если он у них есть, чтобы я понимал когда ожидать стабильный релиз и каков прогресс. Например вот так: https://prod.teamgantt.com/gantt/schedule/?ids=843041&public_keys=eXjoWRdx8pM7&zoom=d100&font_size=11&estimated_hours=0&assigned_resources=0&percent_complete=0&documents=0&comments=0&col_width=255&menu_view=0&resource_filter=0&name_in_bar=0&name_next_to_bar=1&resource_names=0#user=&company=&custom=&date_filter=&hide_completed=false&color_filter=&ids=843041
Чтобы я не спрашивал на двачах или в дискорде, а мог зайти раз в месяц и посмотреть как прогресс.
>чтобы я понимал когда
>Чтобы я не спрашивал
Не, это тебе в платные конторы. Очень немногие опенсорсные поделия могут себе позволить такую степень серьёзности, чтобы прям тебе всё было удобненько, сорян.
Было бы круто, но нет, нихуя, ожидать серьёзного плана с аннаунсментами и майлстоунами от трёх с половиной анонимных школьников - неее...
Этим анонимным школьникам заслали бабла. Ну и на всякий случай, я ничего не требую, а лишь говорю что для популяризации проекта было бы неплохо иметь в легком доступе подобную информацию. Хотя бы в минимальном виде: "релиз 0.11 ожидается через 3 месяца, и мы опять сломаем обратную совместимость, сорян пацаны".
Ну что, какова вероятность что вот эту няшность загнобят сярпо/жсниггеры?
Лично мне что-то прям шишка стоит от постфиксного await. Показал дружку и он грит, вообще не читаемо
Думаю вероятность этого крайне мала.
> вообще не читаемо
Он прав же. Вообще хуевое решение, как кажется. И аргументировать это в том числе тем, что "подсветка в иде поможет" это такое себе. Хуевый язык, если без подсветки писать нельзя.
Может я читал через жопу, но в статье так и не увидел чем же постфиксный вариант лучше.
let Vec<Option<T>> = vec![None; 999];
и тут оно меня радует
the trait `std::clone::Clone` is not implemented for `Entry<T>
бля, сцук, конпилеру какое дело, чего там T имплементит, когда у нас одни None? Я бы не бухтел, но оно же даёт сделать
let Vec<Option<T>> = Vec::with_capacity(999);
Что мешает сразу при создании нонами забить и всё?
https://doc.rust-lang.org/std/macro.vec.html
> This will use clone to duplicate an expression, so one should be careful using this with types having a nonstandard Clone implementation. For example, vec![Rc::new(1); 5] will create a vector of five references to the same boxed integer value, not five references pointing to independently boxed integers.
ну типа шо оператор ?, который будет юзаться практически всегда с асинками сделает из раста лисп. а с постфиксом чейнить foo().await.bar().await станет чуть читабельней
Но ведь есть нормальный вариант await pizdets. Насколько мне известно, оно сделано так почти везде (питон, джс, шарп из того, что трогал), и выглядит оно, ну, нормально. Собственно хули бы так не сделать то? Нахуй выебываться и делать какой-то специальный кейс, где у нас ебучий .await синтаксис?
Вот тут должно быть подробней:
https://paper.dropbox.com/doc/Await-Syntax-Write-Up-t9NlOSeI4RQ8AINsaSSyJ
Сейчас сам прочитаю и кратко перескажу.
Мне лично вообще-то нравится угашенность Раста, но вот этого пидора двачану.
Некоторые решения используются везде просто потому что они лучше всего подходят к задаче.
Не надо без нужды усложнять людям перекат из других языков.
Если вкратце, то использование префиксного варианта выглядит уебищно в сочетании с обработкой ошибок:
(await future)?;
(await future).context("An error occurred.")?;
А т.к. асинк почти всегда связан с IO, то почти в любой асинк операции будет обработка ошибок.
future.await?.foo.await?
vs
(await (await future)?.foo)?
Ну сравни синтаксис на промизах из жс с async/await там же.
Тут такая же история, только текущая асинхронщина еще менее читабельная.
в дотнете примитивами (не очень) синхронизации и ручным пердолингом потоков. выглядит так себе, хотя для большинства случает синхронная версия шустрее асинхронной из-за отсутствия переключения контекста
Я например в языке недавно, но чёт не могу представить, почему бы это было ненормально. Везде и всегда так делали, разве нет?
Ого, разница почти в два раза. Так и думал, что есть какой-то более оптимальный способ. Откуда вот его взять надо было? Не измерять же время каждый раз -- больно много телодвижений. По питону вот для таких задач часто в книгах пишут, что быстрее работать будет или просто как лучше сделать, потому что, мол, питон вообще не про производительность, а лапша будет выглядеть куда хуже, чем просто запилить set. А тут как быть? Не помню, чтобы видел что-то такое в растбуке.
Для этого нужно изучать матчасть.
У способа с сетом сложность o(n), в то время как у вектора с сортировкой как минимум o(n lgn). То есть в теории сет быстрее, но на малых n вектор дает преимущество. Это не привязано к языку особо.
так и знал, лул
в качестве альтернативы (правда, затратной по памяти) можно было использовать хэшсет рядом с вектором, чтобы не форсировать сложность дистинкта в N х log(N)
я имею ввиду задачу дедупликации для вектора решать путем создания хэшсета. в реализации dedup(), а не подразумевать, что вызывающий код накатил sort() сперва
ну пчему. для задачи когда у меня есть здоровенный вектор и мне нужно получить тот же самый вектор без дубликатов и без перестановки элементов. это рядовая задача на каких-нибудь шарпах, например
а, ну бывает
хоть это и сторонний крейт, лол. но для опенсорсного языка это не так уж и удивительно
То есть, лезть в исходники и смотреть реализацию? Сложна.
Интересно, начиная с какого размера хэшсет быстрее будет?
Если вкратце, то не еби мозг. Сделай как проще и читабельней.
1. как и почему Arc реализует Send? Ведь перед передачей в другой тред нужно сделать clone, иначе работать не будет, а после clone это уже другой экземпляр, вроде как.
2. вот есть у меня какая-то структура, я сказал конпелятору, что вот, мол
unsafe impl Send for MyStruct {}
что, уже можно передавать в потоки, не оборачивая в Arc? Ну, на чтение, хотя бы.
> Не измерять же время каждый раз -- больно много телодвижений.
Как раз это и советуют везде.
>после clone это уже другой экземпляр, вроде как
Это всего лишь другой экземпляр указателя, который инкрементирует внутренний счетчик ссылок (Arc - atomic Rc, Rc - reference counter).
>что, уже можно передавать в потоки, не оборачивая в Arc?
Можно, но лучше не стоит. Многопоточное чтение будет работать нормально только со значением, которое не меняется.
Thanks.
есть
src
-- grammar
---- mod.rs
---- nodes.rs
---- trees.rs
-- main.rs
чтобы достучасться из main к каким-то структурам в grammar::nodes, мне нужно обьявить mod.rs в grammar и ре-экспортировать "модули", которые нихуя не модули, а просто файлы *.rs
чтобы тесты в каком-нибудь trees.rs запустились, мне нужно их подсунуть поближе к мэйну, иначе карго их просто не увидит. та даже обычный код не компилится, если он не экспортирован чем-то, что от точки входа идет вниз по дереву пути. вангую, что бинари не совсем должны содержать в себе тесты и карга имеет полное право скипать то, что не попадает под его поле обзора
но у меня даже с тестами периодически возникает какая-то борода, как на пике. компилятор успешно подсвечивает ворнингами то, что некоторые методы и структуры, которые обьявлены парой строк выше, не используются. но тестов мы не видим в упор. объявление модуля tests как публичное было уже шагом отчаяния, но и это не спасает
1. почему у меня не ранятся тесты, обьявленные в файле, хотя структуры и методы в нем же проходят компиляцию?
2. почему пути в расте - это такой леденящий душу пиздец?
Попробуй идейку - мне она автоматом перенесла тесты в отдельный файл и все импорты прописала.
Алсо
>.exe
фи
Срочно обратись к врачу, у тебя серьёзные повреждения мозга.
на работе винды, дома никсы /маняоправдания/
soooooqa, какая же она вырвиглазная. а можно одной кнопкой сделать так, чтобы не хотелось блевать, глядя в монитор?
Ну вот где-то тут настрой
Смотря что раздражает. Если вот эти типы, то disable hints где-то в настройках. Если внешний вид, то попробуй материал тему накатить (в плагинах).
твое выглядит неплохо. но, подозреваю, дело в шрифте, который неконтрастно выглядит курсивный и обычный. попробую пошаманить, хоть и влом
Возможно это тупой вопрос, но лучше я спрошу, чем буду 10лет ебаться.
Это как интерфейсы в ООП-языках. Ты можешь сказать, что функция принимает в качестве аргумента (или возвращает) объекты, которые имплементируют трейт(ы) и использовать его методы, а на то какие конкретно объекты туда поступают тебе похуй.
Ты можешь какой-нибудь своей структуре заимплементить Iterator (всего лишь один метод https://doc.rust-lang.org/std/iter/trait.Iterator.html#required-methods ) и потом получать с этого тонны плюшек (например получить кучу других методов https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods , использовать в фор, в функциях которые принимают итератор, даже другие либы которые принимают итератор смогут работать с твоей структурой).
В расте есть уже куча функций которые принимают трейтнейм, а про твою структуру (которой ты хочешь сделать импл) они понятия не имеют, но если ты прицепишь нужный трейт, то они подружатся и, как итог, меньше придётся своего кода писать.
мог бы просто ответить trait
мне просто первое, что пришло в голову - это кортежи, tuples. но народ че-то про трэйты начал втирать
Батя твой тупль
Тупель.
Как пердэжж
Ай синк уи донт нид ту транслейт уордс фром Инглиш то Рашин. Морове, иу маст ту транслейт Рашин уордс ту Инглиш, бекоз инглиш из мо бьютифул.
Я слышал все три варианта от нейтив спикеров. Их даже георафически не разделишь. Абсолютно рандомно разные люди говорят "тьюпл", "тупл" или "тапл". Иногда даже один и тот же человек.
Это как с either/neither.
Просто белые господа - представители высшей расы работают с tuples, traits and slices, а грязные необразованные пейзане - ебутся с кортежами, типажами и срезами. Неосиляторы тут вообще ни при чём.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=09856d3da0d3ea453e0509daf3e108fc - работает
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6148fab1b7cae90c859ed20904047f99 - то же, но в цикле не работает
Разница в том, что ты забыл итерируешь по вектор по ссылке и делаешь move трансмиттера. Чтобы починить твой пример, нужно его склонировать:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a76813d1f723ab24f50c9c8489e2ef02
Тьфу, блядь:
> Разница в том, что ты итерируешь по вектору по ссылкам, и делаешь move трансмиттера.
Компилятор тебе ровно на это и ругается.
В моем варианте я сделал два вектора и сделал into_iter() по вектору трансмиттеров, соответвенно move спокойно отрабатывает.
https://doc.rust-lang.org/std/sync/struct.Arc.html#method.try_unwrap
>into_iter()
Ясн, типа клонировал с заднего двора его. Могли бы сюда https://doc.rust-lang.org/book/ch16-02-message-passing.html добавить эту тонкость.
Нет там клонирования никакого. Можешь вот тут почитать детальней: https://doc.rust-lang.org/std/iter/index.html
1. у меня есть набор функций, делающих всякое разное, но с одними данными
2. делать разное надо последовательно, но сами данные неплохо бы обработать параллельно
3. написать бы для этого единую ф-цию с дженериками, чтобы параллельно звала некую f для данных и возвращала каждый раз разное T
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0ff1efc4efdca01c2e09e6a1cfa4e29b - nikaque
да, я всё ещё ни хуя не понял
https://doc.rust-lang.org/std/ops/trait.Fn.html
Конкретней надо. Покажи пример данных и функций.
Упс, не то
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=35c3ca7bf1ee29837296f863a918b00e
Не в дженерик виде оно у меня есть и работает - с вызовом известной функции проблем нет. А вот если снаружи передавать, то никак.
Почему бы не использовать Arc? https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=30cfd5c0f2572058d7625574fc2d020c
Какая связь между статик-лайфтаймом и утечками?
Нужно научиться читать сообщения компилятора, он подсказывает что и куда нужно добавить.
> Быть может всё дело в щепотке dyn?
dyn - динамическая диспетчеризация, impl (или шаблонные параметры) - статическая. Можно заменить dyn Fn(usize) -> R + Sync + Send на impl Fn(usize) -> R + Sync + Send + 'static, но тогда использовать Arc уже не имеет смысла.
>The Little Book of Rust Macros
на сие поделие стоит тратить время, или может в Programming Rust про макросы рассказывает поадекватнее?
Возьми и закешируй. Вопрос был про то как писать в стрим, а не про то как это делать эффективно.
С хуя бы? Непрямой доступ к памяти по дефолту более медленный чем копирование пары слов через стек или регистры. Вопрос в том, в какой момент копирование plain-old-data структуры становится более дорогим, чем обращение через ссылку.
У тебя запись в стек идет через L1, т.е. тебе надо часть кэш линий вытеснить из L1 для записи новых значений. Если они уже записаны в L2 или не менялись, то все хорошо. Иначе ждать пока запишутся в L2. В принципе конечно возможна ситуация что вершина стека и прилегающие области находятся в L1 недавно был вызов функции и возврат из нее - тогда тут все будет проще.
С другой стороны ссылку можно и через регистр передать, а если с данными недавно работали, то они будут в L1.
Мое мнение: тут без бенчмарка нельзя сказать ничего определенного.
Угу. Короче понятно, что ничего не понятно и надо измерять.
Как правильно такое писать?
Потому что это
> pub prev: Option<Weak<RefCell<Node<T>>>>,
выглядит ужасно.
Вот так: https://doc.rust-lang.org/std/collections/struct.LinkedList.html
А вообще это одна из худших структур данных, так что подумай зачем оно тебе вообще нужно.
Рискну предположить, что если ты не совсем уверен, как такое писать, тебе лучше воспользоваться другой структурой.
>одна из худших структур данных
оригинальное заявление. если бы каждая структура данных не была заточена под свою задачу
У списков одни из самых хуевых характеристик для типовых задач. Иногда в редких случая они нужны, но чаще всего нет. При этом по какой-то причине эти списки пихают бедной студентоте в начале обучения.
В лиспе и хаскеле списками еще можно обмазываться, но не в расте же.
>по какой-то причине эти списки
Потому что если студентоте сразу дать красно-чёрные деревья или пытаться объяснить A* по графу, у них мозги вскипают. А если начать со связанных списков, то оно проще заходит.
Ну так начинайте с векторов, хештаблиц и бинарных деревьев.
Впрочем да, если надо научить работать с указателями и не проебываться с граничными случаями, то списки хороший пример.
Я так-то хз, но у нас предмет "Структуры данных" как раз и начинался с хешей и простых деревьев и там дальше. Но чтобы хотя бы это понимать, вводный курс, там где совсем банальщина, CS101, там списки были, чтоб пойнтеры осознавать начинали потихоньку.
комплексую чего-т. Зато я за режимы работы транзистора 3 раза пояснять сдавать ходил. Такой вопрос - есть в треде расто-пофессионалы (кто кодит на нём за деньги) или одни любители собрались?
О, молодец. И как оно?
Ещё вот такое:
where F: Copy+From<f32>+std::ops::AddAssign+std::cmp::PartialOrd+std::ops::Div<Output = F>
можно как-то проще обозначить, что я хочу всего-лишь задать обобщённый тип с плавающей точкой? Возможно даже всего из 2х вариантов: f32|f64
Вот это охуенное упущение дизигнеров языка. Хотя бы в рамках примитивных типов могли бы сделать. Чтобы я писал что-то вроде
<T: PrimitiveFloat>
а потом мог бы спокойно писать 'as T' и всё такое
Что именно? Раст охуенный, но не идеальный. Время компиляции подбешивает, и тулинг хочется получше.
> А вообще это одна из худших структур данных, так что подумай зачем оно тебе вообще нужно.
На самом деле мне нужно было минимальное trie для задачи на hackerrank, но у меня возникли проблемы с портированием работающего прототипа на питоне. Решил загуглить реализации простых структур данных на расте, вот и наткнулся на ту ссылку.
Почитал исходники LinkedList, это определенно лучше, пусть и с unsafe, но в итоге я забил и просто запихал все ноды дерева в вектор, а вместо указателей сделал индексы на него.
>Раст охуенный, но не идеальный. Время компиляции подбешивает, и тулинг хочется получше.
Две виртуалки с ансиблем этому инженеру.
Это почти как спрашивать, почему встроенного вебсервера нет, лол. Потому что разрабам не показалось это важным.
Сделай. Нужно всего-лишь потребовать, чтобы у типа был унарный минус и операторы сравнения.
Хорош ли раст для разработки стрименгово сервиса? Или лучше взять Erlang/OTP?
Yasno
Конечно можно. Ну вот смари: мне для функции, работающей с дженериком F, нужно писать такую ебалу:
where F: Copy+From<f32>+AddAssign+std::cmp::PartialOrd+Div<Output = F>+Sub<Output = F>+Neg<Output = F>+Add<Output = F>+Mul<Output = F>
хотя F у меня может быть либо f32, либо f64 - и вот для такого простого случая нужно городить такой огород (причём, его приходится тащить в каждую функцию). Хотя можно было бы изобразить что-то вроде F: (f32|f64) или тип того. Про сторонние крейты знаю, не предлагать.
То есть, с одной стороны в языке куча сахара (как компенсации за ёблю с бч), а с другой - нет такой элементарщины.
Ещё нашёл #![feature(trait_alias)] - оно в анстейбле. Зато с ним можно так
trait X<F> = Copy+From<f32>+AddAssign+std::cmp::PartialOrd+Div<Output = F>+Sub<Output = F>+Neg<Output = F>+Add<Output = F>+Mul<Output = F>;
и потом писать везде
where T: X<T>; //Пиздец, не правда ли
но всё равно костыль, да и не факт, что даже его стабилизуют.
Чур внешними костылями не бросаться. Я про то, что должны быть или типы высшего порядка, или чего-то вроде возможности создать свой по типу union.
>Чур внешними костылями не бросаться.
А я не совсем понимаю, почему тебя внешние костыли не устраивают.
А нахуя ты изобретаешь велосипед? Есть же pest.rs, который сгенерит тебе синтаксическое дерево и парсер под него по описанию грамматики, всё на этапе компиляции, без оверхеда времени выполнения, ты всё равно лучше в жизни не напишешь.
Но это интервью 2012 года, раста тогда еще не было.
Тем, что это костыли под специальный случай, а я хочу вообще. Может у меня вообще так случится, что T будет в диапазоне от u8 до f64.
>То есть, с одной стороны в языке куча сахара (как компенсации за ёблю с бч), а с другой - нет такой элементарщины.
Элементарщину реализовать можно средствами языка, а сахарок нет, лол. Ты не можешь ожидать, что любая херня, которая тебе только может понадобиться, окажется в стандартной либе, она не для этого.
>>405085
Там уже есть трейт Num, который покрывает любые операции над числами. Чувак сам не знает, чего хочет.
>Там уже есть трейт Num, который покрывает любые операции над числами
дженерики он хуёво покрывает. Даже если T: Float, я всё равно не смогу написать
2.3T
или
2.3 as T
при этом, внезапно, он не включает std::convert::From<{float}>
поэтому даже into() с ним одним не заведётся.
>Fn closure traits implemented for Box<dyn Fn>
почему мне делегат нужно все-равно упаковывать, ебанаврот. после дотнетовских анонимных функций как-то сложно уговаривать компилятор не ругаться. хотя, и язык не о том
Делегат-дегенерат. Почему объебки из микрософта всегда придумывают какие-то новые термины для простых устоявшихся вещей?
ну closure - это немного не о ссылке на функцию, а о доступе к данным вне её. это даже в жявяхуяваскрипте замыканием называется
или о чем ты?
ссылка на метод
>объебки из микрософта
У тебя ответ в самом вопросе. Блядская компания, блядские продукты, блядская культура и блядское комьюнити.
Он про майкрософт-онли фанатиков, которые на каждом углу орут о том какой си-сярп охуенный, не видя что им подсунулу перекрашенную жабу.
Но visual studio code - единственный редактор, в котором можно нормально разрабатывать на расте в 2к19.
Как жить-то?
Сам не понимаю, бред какой-то. Парадокс. Пытался Атом это самое, вроде неплохо, туда-сюда, но VS-выродок всё равно лучше.
Часть плана MS по угнетению опен сорса, наверное. В линупс они три года назад вкатились, гитхаб в прошлом купили, ждём когда вся экосистема накроется медной пиздой.
https://en.wikipedia.org/wiki/Embrace_extend_extinguish
Если ты готов мириться с электронными тормозами, то живи с ним.
Емакс и вим никто не отменял в 2019.
За вим ничего не скажу, но удача как раз нужная тому, кто через дерево-файлов или прости господи табами пользуется.
Это примерно такое же днище как альт-табаться постоянно.
А чем надо пользоваться, когда у тебя вложенность в 4-5 директории, ручками вбивать все пути как додик?
Ну это заебись, пока у тебя 4 файла в одной папочке, когда у тебя будет 50 в 10 папках, так же будешь щелкать, пока белый человек один раз кликнет на файл в дереве проекта?
Хз, в моем хобби проекте 300+ файлов в хуй знает каком количестве директорияй. Как по мне если бы мне надо было щелкай мышкой для навигации, я бы повесился.
Недавно видел относительно удобно настроенный neovim для раста и не только:
https://www.youtube.com/watch?v=ycMiMDHopNc
Про вим начинается в 13:45, c 17:00 работа с файлами через fzf.
А никак не могу заставить его схавать 2 итератора. Можно, конечно, сделать flatten и collect, но как-то некошерно.
И, к вопросу о внешних костылях, он работает только из гита, в репах сломанная версия.
>в репах сломанная версия.
если у тебя ночной конпелятор, то это может не в репах сломана версия, а конпелятор у тебя несовместимый
Это SIMD, он только с ночником и совместим. А так, если в мастере типа нестабильная версия, но работающая с последним ночником, а в репе стабильная, но работающая с конкретным ночником - дак могли бы указать версию ночника-то.
нашёл эту либу, заюзал, решил попробовать с генератором. А его и нет. Лезу в сорцы - и правда нет, но: для передачи в train() ему и не нужен полный датасет, всё необходимое вынесено в отдельный трейт с 3-мя методами, который мне и осталось заимплементить для своего генератора.
И вот он продумал же, малаца прям.
Но одно пугает - все МЛ проекты на расте либо совсем новые, либо застопорились в 2018 и раньше.
https://github.com/autumnai/leaf есть постарее и он даже был относительно популярным, но умер.
Как по мне, это говорит о том, что энтузиазм вокруг раста велик, но самих энтузиастов пока мало. Сначала у человека хватает энтузиазма реализовать что-нибудь эдакое, но потом для продолжения ему не хватает фидбека в виде багрепортов и донатов - и всё стопится.
Ещё заметил, что авторы таких проектов зачастую студенты, которым после окончания обучения надо что-то кушать.
https://medium.com/@mjhirn/tensorflow-wins-89b78b29aafb причины тут. Датасайентистам проще питон. Торч который без Пи скорее всего по этой же причине менее популярен.
а зачем:
mut peremennaya_name: &mut ImyaTipa
?
Пуританин в треде, лол.
Совсем сумасшедший.
структура файлов простая:
/src
|_ utils.rs
|_ types.rs
|_ tests_1.rs
|_ tests_2.rs
utils ссылается для своей работы на types. tests шо 1 шо 2 ссылается на общий utils.
сам проект целиком и полностью состоит из тестов на уже развернутое независимо окружение (конечно, лолблядь, но это просто по гайду ради примера)
если в Cargo.toml указать [lib] path = "src/tests_1.rs", но по-отдельности потестить тесты получится. но чтобы запустить все разом, я хочу объединить их в каком-нибудь ентри-поинт файле. например main.rs:
mod tests_1;
mod tests_2;
src/tests_1.rs:
file not found for module `types`
help: name the file either content\types.rs or content\types\mod.rs inside the directory "src"
я перепробовал еще вариантов экспорта, но там либо uknown crate или синтаксическая ошибка.
как воркэраунд я надекларировал в Cargo.toml [[bin]] с путями, а в тест-файлах создал пустые fn main(). но это какой-то кек, как по мне. вообще есть адекватный способ создать иерархиеские зависимости модулей в пределах одного уровня директорий?
https://doc.rust-lang.org/cargo/guide/tests.html
Если смотреть сюда, то по логике просто сложи тесты в папку tests рядом c src. В таком случае импортить имена надо будет через use {crate_name}::...; но в таком случае надо иметь lib.rs или эквивалент, который будет экспортировать модули наружу через pub mod;
Но вообще я ещё ни разу так тесты не отделял, предпочитаю писать их рядом, через
#[cfg(test)]
mod tests {
use super::*;
...
}
Вообще, насколько я понимаю, твоя проблема в том, что ты не включаешь тесты в зону видимости, тебе надо указать все модули, которые ты используешь, в lib.rs. Например, когда у тебя не находится types.rs, который вроде бы как рядом, это потому что ты не указал его в lib.rs. Чтобы было понятнее, представь lib.rs корнем дерева, из которого исходят модули-ветки, из которых тоже могут идти ветки.
Допустим, есть lib.rs, в котором есть
pub mod module;
pub mod module2;
Поскольку ты их указал в lib.rs, ты можешь импортировать имена в модулях module и module2 через
use super::module::{...};
use super::module2::{...};
или
use crate_name::module(2)::{...};
Поскольку модули являются дочерними сущностями относительно корневого lib.rs, именно поэтому в lib.rs надо указывать все модули, которые собираешься использовать(а если не хочешь включать модули с тестами, используй #[cfg(test)] перед pub mod test_1;.)
Та же ситуация с mod.rs, в нем ты должен указать дочерние модули, если они у тебя есть.
Сорри за форматирование.
sed -i -E 's/(unsigned int )([_a-z]*)/\2: usize/g' src/file.rs
думаю, это будет бриллиант в моём портфолио. Все просто охуеют, да я и сам охуею, если получится. Но пока я это конпелятору даже не пытаюсь скармливать, сперва перепишу грубо и грязно, потом перепроверю, а потом буду функцию за функцией вытягивать и обмазывать тестами.
а что у вас?
> Я вот тут взялся один известный опенсорсный проект с сей на раст переписывать.
Нахуя тебе этот бриллиант? Либа уже есть, нахуя делать всё то же самое, только на расте? Напиши лучше свой собственный, оригинальный бриллиант.
Оче просто. Либа:
- хорошо отлажена в плане алгоритмов
- раскручена и на слуху
- до сих пор одна из лучших в своём классе
- значительно не обновлялась лет 7, а мне хотелось бы от неё пару новых фич, которые стрёмно реализовать на сях.
> нахуя делать всё то же самое, только на расте
Потому что могут.
https://github.com/remacs/remacs
в линкедине относительно нечасто, но пописывают
Да забей, смысл отвечать этому шизику. Он же тут по всему треду устраивает театр одного семена, "гыгыгы работы нет". Ну хоть тред бампает, и то неплохо.
>>413724
Сам тут взялся разбираться, и понял что нихуя нормального нет. Чо сам пытался осилить:
https://rust-lang.github.io/async-book/ (но там пиздец нихуя не написано, может в версии с гитхаба побольше)
https://tokio.rs/docs/futures/basic/
https://dev.to/mindflavor/rust-futures-an-uneducated-short-and-hopefully-not-boring-tutorial---part-1-3k3 (не нашел полезным)
Просто попробуй сам заимплементить какую-нибудь футуру для начала, потом стрим. Я в какой-то момент заступорился, но вот этот пост помог мне больше, чем все гайды вместе взятые: https://www.reddit.com/r/rust/comments/84y1n1/how_to_implement_the_poll_method_for_the_future/dvu6s2n?utm_source=share&utm_medium=web2x
Кстати да, исходники очень помогают. Еще стоит посмотреть в код либ, где заимплеменчены асинхронные фичи, я вот копался в reqwest::async и hyper.
>>414786
async-book это же про нативный async/await, а не про фьючеры, которые futures = "0.1". разве не так?
или они смерджили тот крейт себе в std?
вообще спасибо за ссылки. исходники - это хорошо, но пока мне сложна в растосорсах копаться с евойными impl for, хотя не отменяет того факта, что надо)
Не за что.
Нашёл https://saschagrunert.github.io/indextree/indextree/index.html
но он какой-то корявый.. Может есть получше?
Рекурсивно делить изображение на квадраты. У каждой ноды будут записаны
- координаты начала
- координаты конца
- Option(родитель)
- Option(вектор с детками)
ну и будет метод gen_children для генерирования деток - внутри координат self выделяем от 4х квадратов и пишем ей в children
Пытался сделать на Rc и лайфтаймах - охуел с того, сколько подводных камней вылазит. А так, хочу, чтобы можно было
> let mut root = Node::new(0, 0, h, w);
> root.gen_children();
> for child in root.children.iter() {
> if child.wants_children() {
> child.gen_children();
> }
> }
А зачем ноде нужно знать родителя? Если такое требование убрать, то можно сделать так:
struct Node {
range : [[usize; 2]; 2],
children : Vec<Box<Node>>
}
Если родитель таки нужен, то добавляй указатель и ебашь через ансейф, главное следи, чтобы твой интерфейс не позволял элиасинга.
Родитель очень нужен, там делается сравнение свойств изображения в дополнительных полях. Ансейф можно попробовать, конечно. А что, конпелятор сам ну никак не отследит, что я не делаю ничего плохого?
Например, такая частая ругань:
> cannot borrow `tree` as immutable because it is also borrowed as mutable
Это было при попытке чтения структуры, после root.gen_children();
Но, ёпта, конпелятор же должен видеть, что
> it is also borrowed as mutable
сделано выше в однопотоке и уже давно завершилось, чилдрены сгенерились, все свободны. Ну нет, мы будем якобы думать, что я там в ниебацца какой поток это передал и оно до сих пор что-то там пыхтит мутабельно и асинхронно.
Сделай Copy тип, который будет индексом в конкретный пиксель оринигальной картинки.
https://crates.io/crates/y4m
Там есть пример
ffmpeg -i in.mkv -f yuv4mpegpipe - | target/release/examples/resize - 640x360 - | mpv -
Вот этот resize тебе и нужен - таки это тоже прокуривание пайпа, но ничего проще не придумаешь.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ae624ce87bcfba81f07f36ee0ebffd8d
там есть закомменченый кусок кода, который не работает - получение деток изнутри ноды. А снаружи, сцук, работает. Хотя, казалось бы - тот же вектор, Arc+лочка на месте, но чего-то не хватает.
Поправил, но выглядит как пиздец, лол.
1. Arc подыхал на той же строчке, в которой клонировался, в результате и по локу к нему было нельзя обратиться. Сделал биндинг для клонированного Арка и уже его лочу.
2. Сделал дерайв Clone для OffNode и кладу n.clone() в вектор.
3. При итерации сделал n вместо &n, не хватает знаний нормально объяснить, в чем разница.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=422a78da56f88ab7c3e215d6e4faad2b
Что это должен быть за алгоритм, наверняка есть нормальный способ его написать?
От души. Как раз это нужно было.
> n.clone()
блин, не то, как мне для самой-то n деток генерить? Вообще, заметил нехватку такой вещи: Rust запрещает mut во много потому, что это подразумевает возможность деструктивных действий типа удаления. Например, храню я ноды в векторе, надо что-то сделать:
1. вынимаю дочку из вектора
2. передаю вектор дочке, чтобы она напихала себе в него ещё дочек.
конпелятор такой:
вай-вай, щито ты делаешь, а вдруг дочка удалит родителя?
а я ему: мамой кланус, не удалит!
а он мне: на си будэшь класться, а пока иди домой!
дак вот, может есть промежуточный вариант, когда мы одалживаем вектор мутабельно, но с запретом на удаление, только для добавления? Костыльно я мог бы и сам это сделать так:
получить от дочки вектор с её детками и разложить его самостоятельно. Но эт как-то жопно.
пердолься с трейтами, заверни вектор во враппер, который будет имплементить Delete и Insert. там где нужно возвращай impl Delete/Insert. interface segregation типа
Мысль хорошая, но боюсь, что не взлетит. Лан, попробую, потом всем тредом подумаем, прав конпелятор или нет.
честно говоря, я не понимаю твоей мысли
если тебе нужно мутировать объект, ты передаешь &mut X или mut X. причем, где принципиальная разница в качестве мутации между добавлением данных в структуру или удалении их оттуда? почему элементарная перестановка значений в векторе менее деструктивная операция, чем удаление какого-либо элемента?
мы говорим не о бизнес-логике в целом, а о представлении компилятора на происходящее офк
если так, то какой выход из этого всего? &'static self компилятор тоже заворачивает лол, да и это понятно
и тут я посмотреть на своё кодэ и понял, что все очень-очень плохо
лучше ли будет возвращать Future из send_message, а место отправки сообщения обернуть через tokio::spawn? но тогда, суда по всему, для T нужно добавить будет констрейнт Send?
Ну не теперь, а давно уже, и во-вторых, да, артефакты в target могут быть очень разными, в первую очередь из-за возможных комбинаций фич и статической линковки, в .cargo наверное только сорцы и складываются. Ну и cargo не чистит старые билды, так что будет все печально если не следить за папкой. Надеюсь, скоро начнут пилить что-то по этой теме.
С гордостью рад представить вам получившуюся мега-ебалу (зато идиоматичную!):
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d2390925f3cafc95ddcf1b94243006e6
Для каждого уровня вложения используем отдельный вектор - так на спуске по дереву не возникает пересечений. Пиздеца там наворочено много, конеш, подозреваю даже, что можно обойтись без RefCell и одного Arc - надо будет попробовать почистить.
Да, надо бы Rc.
Оберни во что-нить. В Mutex, например. Или тебе надо, чтобы прочитали одно и то же несколько раз?
Ну если ты просто let сделал, то почему ему не плеваться на тебя? Сделай clone(), если возможно. Вынеси self.address иначе. Что ты, блять, как маленький? И где ты let сделал, на каком уровне вложенности?
> mpsc
> Multi-producer, single-consumer FIFO queue communication primitives.
Ты долбаеб, что у тебя не катят?
Или давай семантику локов определяй
Ну дык, ты в в этом замыкании захватываешь self и потом его возвращаешь, когда возвращаешь футуру (что собственно неправильно, ведь футура может существовать дольше твоего объекта). Сделай .clone() на self.channel_name (у тебя же там String, да?), как говорил анон >>423660 выше, должно быть ок.
в C# анонсировали завоз оператора _, расширение switch-а до уровня похожего на растофункциональщину, деконструкцию (правда, уебищную). как обычно, каждый язык берет что-то удачное из другого и начинает имплементить это у себя. выглядит так себе, мягко говоря
Зачем ты ее вообще сюда притащил? У тебя что, нет жава треда?
Благодаря твоим картиночкам всем становится понятно, почему у тебя так болит жопа.
Никто ведь не обещал, что ебать в жопу будешь ты, а не тебя.
Я нихуя не понял из того, что ты написал. Про какую-то хуйню, кого-то ебать в жопу, у кого-то болит жопа, просто охуеть.
Но у меня сложилось впечатление, что ты думаешь, будто я пишу на этом блядоязыке для телевизоров. Уверяю тебя - ты ошибаешься.
Однако, думаю, что тебе стоит обратиться за профессиональной помощью с твоей анальной фиксацией.
Ну хз. Типа есть "Rust by Example", фактически от разработчиков, очень похож на О'Райли, но Rust by Exampler лучше структурирован и не устарел морально (ибо фиксится периодически). Так что лучше прочитать Rust by Example уж тогда, держа под рукой растбук на случай непоняток.
Что там за драма у вас? В раст протекли плюсовики и хотят пердолиться в указатели?
Хуй знает, попалось на реддите
https://www.reddit.com/r/rust/comments/ceevlw/i_am_really_disappointed_in_rust_community_for/
Видимо, нельзя.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c10fb4d3fd86d59627bf5b38e984166c
Делай явное преобразование типов.
Теперь всё ебало в кастах. Ну, чтож, спасибо и на этом.
С одной стороны явное преобразование всё же лучше неявного, но с другой стороны код получается уродским.
Я, конечно, вона в какие замыкания могу, но некрасиво же.
Если реально дохуя кастов выходит, то можешь сделать newtype и для него уже реализовать то что тебе нужно. Из твоего скрина не очень ясно откуда какие числа берутся, но self.pc ты точно можешь завернуть в newtype и реализовать для него ужные действия. Еще не забудь накинуть на свой новый тип #[derive(Copy)], и выйдет вполне няшно, ну и Display возможно тебе еще придется реализовать элементарный (если много таких типов будет, то есть хороший крейт newtype_derive + macro_attr. Еще из плюсов такого подхода выйдет compile-time проверки типов передаваемых в функции (не знаю нужно-ли тебе это, но точно лишним не будет).
Что-то мне подсказывает, что можно лучше, но из коробки вулкан предлагает только обрезку и повтор. Ведь прямоугольников будет много, они будут морфировать, не переконпелять же шейдер каждый раз.
Они у меня и так есть, толку-то. Мне нужно натянуть квадратную текстуру на условную трапецию.
Вот так я сделал это на расте
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8ad2240a8e2dedf850c7a988a837d6ff
только внешнюю область не отсёк, ну и так всё понятно
Т.е. ты начал спрашивать до того, как загуглил? Если бы не наша приверженность Code of Conduct, тебя бы уже покрыли хуями.
Я гуглил, потом спросил, потом ещё погуглил. И да, я таки до сих пор не уверен, что это то, что мне нужно.
Я так и не понял, почему тебе в массив вертексов не ложить сразу трапецию, и вот на неё уже натягивать текстуру. И это даже необязательно делать в шейдере. Ужас-ужас, придется использовать математику, но что поделать.
>сразу трапецию, и вот на неё уже натягивать текстуру
Дак о том и вопрос - как? Шейдером с математикой я уже натянул, вот только это штучное неоптимальное решение.
1) По сети программе прилетают пакеты.
2) Каждый пакет промаркирован некоторым тегом.
3) Тегов 100500 x 9000 x 1337 разных штук и могут появляться новые, программу из этого разнообразия интересуют всего 20-30 идущих не по порядку (сначала 42, потом 146, потом 228 и т.п.).
4) Что хотел сделать я: загнать эти 20-30 тегов в Enum и сделать match по значению с дефолтным вариантом. В C было бы примерно так же.
5) Что выяснилось: в Rust так сделать нельзя. Начиная с того, что нет нормального способа сконвертить u32 в Enum. Есть std::mem::transmute, но программа будет падать, если значение не попадает на одно из описанных в Enum. Описать Enum со всеми значениями не представляется возможным чисто практически. Описать Enum с условно "дефолтным вариантом" типа Other(u32) не позволяет уже компилятор - discriminator values can only be used with a field-less enum. Каким-либо здравым образом проверить принадлежность значения Enum перед конвертацией чтобы реализовать метод типа from(u32) -> Option(Enum) тоже нельзя (можно просто создать новый массив, где перечислить все значения Enum as u32 - а если появится новое, его что, вручную вносить в два места?).
Можно не преобразовывать полученный u32 тэг в Enum, но тогда либо match превращается в ужасное говно вида "x if x == Enum::SomeValue => ...", либо вообще придется отказаться от Enum и в match засунуть цифровые значения тегов, подписав их в комментариях.
ЧЗХ, посоны? Почему Rust не может просто и красиво сделать то, над чем в C даже думать не приходилось?
Макросы ведь есть вроде
> ЧЗХ, посоны? Почему Rust не может просто и красиво сделать то, над чем в C даже думать не приходилось?
Потому что ты криворукий шизофреник (твой бред ОЧЕНЬ сложно читать).
> нет нормального способа сконвертить u32 в Enum
> реализовать метод типа from(u32) -> Option(Enum) тоже нельзя
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1e7ed7ab02a98a7c783877330380e177
Единственная проблема, которую я смог (вроде правильно) понять из твоего текста.
> даже думать не приходилось
Ну да, хуяк-хуяк и сегфолт. Тут так нельзя.
Документацию я облизал вдоль и поперек, от книжки до by examples и nomicon. Нигде не нашел решения.
>>442155
>Потому что ты криворукий шизофреник (твой бред ОЧЕНЬ сложно читать).
Спасибо на добром слове, я тоже тебя люблю. Описал все максимально кратко и понятно, может быть, несколько эмоционально.
>Единственная проблема, которую я смог (вроде правильно) понять из твоего текста.
Я в тексте же и описал ее потенциальное решение. Ну да, можно сделать и так, как ты написал. Но у меня этих значений не 2, а 20-30, причем они могут добавиться в перспективе. Это все в match пихать? Не говоря уже о дублировании информации.
>Ну да, хуяк-хуяк и сегфолт. Тут так нельзя.
В том и дело, что сегфолт как раз можно (при помощи unsafe, правда - transmute), а вот сделать Enum, у которого часть значений была бы описана явно константами, а часть явно или неявно (как в C) опускалась - невозможно даже с помощью unsafe.
Вот тебе пример того, что я пытаюсь сделать (на плюсах, правда, не на C, но это мелочи):
http://cpp.sh/6jlnh
Как такую же простую, примитивную и встречающуюся на каждом шагу штуку завернуть в расте?
Впрочем, кажется, я уже подобрал решение. Не очень красивое, но, по крайней мере, без особых проблем. Associated constants спасут отца русской демократии. Если есть вариант интереснее - буду рад услышать.
Спасибо, принимается. Я не нашел, плохо искал, видимо.
// Хотя я все равно недоволен тем, что такие простые и базовые для любого системного языка вещи приходится костылить через левые пакеты. И ох если бы это был единственный пример... Весь Rust из такого состоит.
А ты перестань мыслить сишными категориями и всё пройдёт. Зато теперь ты можешь любой набор байт превратить в этот Option<EnumType> и не потеряться по коду, что он и зачем. Это гораздо лучше, чем таскать число, постоянно держа в уме, что вот оно вроде число, но тут мы ещё проверим его на соответствие возможным значениям EnumType, поэтому это как-бы EnumType, но как-бы и не он.
>а вот сделать Enum, у которого часть значений была бы описана явно константами, а часть явно или неявно (как в C) опускалась - невозможно даже с помощью unsafe.
Тогда это вообще не енум, а хрень какая-то, тебе проще сделать 20 именованных констант в неймспейсе и матчить с интами. Более того, так даже в Си часто делают.
1. 90% либ на жабе - костыли, нужные, чтобы хоть как-то этим говном без слёз пользоваться.
2. 100% либ на жабе - тормозное говно, ибо иначе на жабе никак
3. добровольно пишущих на жабе опенсорс just for fun почти нет. Опенсорс проекты на жабе, это либо под ведроид, где выбора нет, либо корпоративная отрыжка в апачеотстойнике.
так что, ты не бог, то просто макака, которой белые господа за банан поручили написать реализацию интерфейсов. В этом вся суть жабы: в разделении на господ и макак, что очень удобно для менеджмента.
1. Сахарный из коробки. Итераторы, вывод на печать чего угодно, автовыведение типов, туплы. Сахарность почти как у питона, сам с него пересел. Сравни с жабой, где для каждой мелочи на stackoverflow предлагают городить костыльный класс на пару экранов.
2. Быстрый и нативный. Жаба в этом сливает даже питону, у которого каждая третья либа пишется с использованием cython или c.
3. Строгость и многообразие типов. Есть даже беззнаковые целые, прикинь.
4. Есть борроу-чекер. Конпелятор сам следит за тем, чтобы ты, мудила, не устроил data-race. Жабе тут вообще похуй - хочешь, используй атомики и мьютексы, а хочешь - нет и получай андефайнд бехэйвор.
лучшее, что может случиться с жабой - если её языковые возможности подтянут до раста. switch, вон, делают, знаковые собираются завезти. Т.е., чисто в теории, если пофантазировать, что они в 1000 раз ускорят её развитие, то по удобству она будет на уровне раста. Но, сцук, по скорости и потреблению ресурсов - как сосала, так и будет сосать. А по факту сосёт по всем параметрам, даже не знаю, что может заставить кого-то писать на ней, кроме большого бабла.
Если ты работаешь с чем-то типа TcpStream, можно попробовать установить set_read_timeout. Если что-то другое, реализующее Read, то наверно читать маленькими буферами и копировать байты куда надо. Можно еще попробовать поиграться с асинхронщиной через AsyncRead.
А вообще если ты сидишь на юниксе и просто копируешь байты из А в Б, мне кажется, что проще просто работать с сырыми дескрипотрами и через dup2 (https://docs.rs/nix/0.14.1/nix/unistd/fn.dup2.html) перенаправить куда надо.
Нашёл, нужнo передать как stmt
macro_rules! unsafe_and_check {( $expr:stmt ) => (
let status = unsafe { $expr };
assert_eq!(status, OK);
)}
теперь другой вопрос - можно ли вывести на печать стейтмент?
>stringify!
Воу, пасибо тебе, братишка. Получился такой макрос для вызова сишных хункций с возвратом статуса, будь они неладны.
macro_rules! unsafe_and_check {
( $stmt:stmt ) => (
let status = unsafe { $stmt };
assert_eq!(status, OK, "Got status '{:?}' when call {:?}", status, stringify!($stmt));
);
}
Почему rust до сих пор не взлетел? В то время как go уже стал стабильной частью ынтырпрайза.
Потому что Go это про быстренько запилить очередной REST API. А Rust это про системное программирование, которым занимается не так много народу.
Это копия, сохраненная 21 августа 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.