Вы видите копию треда, сохраненную 2 августа 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
создавать надёжное и эффективное программное обеспечение
async/await наконец-то в стабильной версии!
https://www.rust-lang.org
Вместо шапки: https://gist.github.com/TatriX/183c816f1346d418f969c4576c2b9b41
Предыдущий тред: >>1539530 (OP)
Зато те кто осилили, кайфуют.
такое дело: vulkano как раз генерит шейдер из процедурного макроса, т.е. код шейдера должен быть известен ещё до конпеляции. А я хочу через темплейт нагенерить 100500 вариантов шейдеров и матчилку для их разруливания. Короч, решил заюзать markup + build.rs - пожелайте удачи, в-обсчем.
Просто у вас токсики-нацисты в сообществе. Последний случай с веб-сервером на расте и его выпиливанием с гитхаба весьма показательный пример для желающих вкатиться в ваше говно.
Так во всех небольших коммунити. Ненависть, желчь, недружелюбие к новичкам, сектантство.
Скажем я хочу хэш таблицу на сях, например, String -> Int. Сравним с питоном или растом?
Ну так сишка сложная, там потратишь на разработку намного больше времени. А питон любая школьница осилит и решит прикладную задачу в десятки раз быстрее.
Словарь в питоне есть из коробки. В сях хеш-таблицу придётся реализовывать с нуля, либо брать либы.
О чем и речь.
По опыту - совсем не подходит только для GUI (почти все фреймворки - говно, обвязки над qt/gtk - ещё хуже, да и как-то в целом язык, как кажется, не очень помогает), фронтенд (тащемта профитов мало, придется компилить в васм, ну нахуй, проще взять TS).
Ещё (довольно узкий) кейс - система плагинов в виде динамических библиотек. Если хочешь DLL с растовым интерфейсом (трейты/трейт объекты/не С типы данных), то соснешь хуйцов, так как супер сложно обеспечить совместимость потом будет.
В остальном для всего подходит, а с excvr можно даже как repl юзать.
Есть Askama, как раз компилит шаблоны в compile-time. Для рантайма есть Tera. Оба по сути варианты Jinja2.
Сам сейчас на работе юзаю Askama, очень неплохая штука. Не уверен, насколько она подойдёт для шейдеров, но раз ты упомянул mako, то наверно тебе сойдёт.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust.html
А в некоторых не даёт. Удивительно, да?
Есть мнение, что по перформансу оба языка находятся у предела для высокоуровневых языков. А перегибы в ту или иную сторону - лишь следствие особенностей реализации оптимизаторов.
Было бы круто, но даже если все двачеры знающие Раст соберутся, путного ничего не выйдет. Слишком сложно.
Запили поддержку 16-бит png для image и/или 12/16-бит жипега для него же. Вообще, под раст худо-бедно либы есть, но многие из них страдают дефицитом функциональности.
Жиза.
Я тут подумал, что широко известные ничего не показывают, кроме знаний авторов о железе и внутренностях раста.
А такой, который бы показал перфоманс идиоматического кода на расте (без строчки unsafe), плюсов, джавы etc.
Обычный клиент Postgres не работает, если программа использует async.
Причем падает с Runtime ошибкой
>Cannot start a runtime from within a runtime.
Ну заебись.
Пошел переписывать на tokio-postgres
Ну как бы да, синхронный клиент это обёртка над асинхронным (https://github.com/sfackler/rust-postgres/blob/master/postgres/src/client.rs#L35), и ей нужен свой рантайм. Но вопрос - а нахуя тебе синхронный клиент в асинхронном коде, а? Ты решил специально усложнить жизнь?
На удаленках выгорел и по итогу нет ни одного проекта нормального проекта для портфолио как и самого портфолио
В реале идти устраиваться не вариант
Где найти силы?? морально хочу начать сосать писюны и сидеть на каком-нибудь винте или герыче нет сил
Никогда не понимал, что такое "портфолио" кроме как для фронтенда или мобилок.
>На удаленках выгорел
>Где найти силы??
Знакомые симптомы. Меняй режим работы.
Сразу говорю мотвация, накачивания себя и прочие психологические штучки тут не помогают.
Что мне помогло:
- Никакого кода после 9-00: Код выходит говно, усталость накапливается, мораль падает.
- Я полностью отказался от кофе в пользу яблок. Кофе дает бодрость не бесплатно, а в долг и требует потом проценты. От яблок тот же эффект, но больше пользы.
- Я встаю в 6:00 каждый день , но это по желанию.
- Ходять в качалку я не стал, купил гирю на 16. Мне достаточно в день делать 1 упражнеие - 10х10 махов гирей. Мышцы перестали атрофироваться и осанка несколько исправлась. Плюс вернулся аппетит.
>Никакого кода после 9-00
утра или вечера?
>в пользу яблок
мне помело помогает, которое фрукт. Адово бодрит
>купил гирю
я тоже себя нагружаю, чтобы ночью спать. Если физически не утомляюсь, ночью не сплю. Только надо подгадывать, чтобы ночью спать, а во время работы - нет.
не тот анон, но тоже удалёнщик. хуячу приложение камеры на расте.
>>Никакого кода после 9-00
>утра или вечера?
Вечера, понятное дело.
Я за ~15 лет работы в IT видел много примеров "ночного" кода.
Собственного, вендорсокого, кода джуниоров, синьеров, тим лидов.
Что весь этот код объединяло - он всегда был говно.
>the maintainer of a popular Rust library (Actix Web), under heavy criticism (some might call it hate), decided to stop maintaining it and quit open source development.
>А где посмотреть бенчмарки раста?
Это немного странный вопрос, потому что сам раст позволяет тебе писать код сколь угодно близкий к железу. Может быть ты хочешь посмотреть производительность stdlib?
Или может ты хочешь узнать как быстро работают программы написанные для синтетических задач? Тогда вот: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust.html
Или для конкретных реальных задач: https://blog.burntsushi.net/ripgrep/ https://github.com/serde-rs/json-benchmark https://github.com/tafia/quick-xml
>Я тут подумал, что широко известные ничего не показывают, кроме знаний авторов о железе и внутренностях раста.
Если ты хочешь делать бенчмарк на любом языке для любой задачи, тебе обязательно придется знать железо и внутренности языка. (в случае с Си этих "внутренностей" намного меньше чем в других языках, и вопрос ближе к железу)
>А такой, который бы показал перфоманс идиоматического кода на расте (без строчки unsafe), плюсов, джавы etc.
Я думаю вот это очень полезно: http://cliffle.com/p/dangerust/
Я вот никогда во внутренности актикса не заглядывал, но вот вспыхнул скандал, и я солидарен, что там по, ансейф ансейфом погоняет.
И как бы оно может упасть в любой момент, никакие гарантии, за что я полюбил Раст не работают.
И скандал не из-за количества ансейфа, а из-за одного вполне конкретного.
Там ансейф в одной функции, которая, вообще-то, тоже должна быть ансейф, и из-за этого кажется, что его мало.
Это не самое смешное. Там до сих пор в лежит в исходниках аналог UnsafeCell, только где все функции помечены как безопасные. https://github.com/actix/actix-net/blob/master/actix-service/src/cell.rs
Одно дело, когда у тебя в ансейфе 22 = 4, а другое, когда 2x = 4, где х - а хуй его знает, скорее всего тоже 2.
У меня, кстати, в приложухе джля ведроида полно подобных ансейф преобразований, без которых никак, ибо коллбэки. Приходится в RefCell оборачивать и пикрил хуетой пользоваться (кстати, мож кто знает - есть ли подобное в стандартной либе?)
> пикрил хуетой пользоваться
Может лучше RWLock возьмёшь из крейта parking_lot? Методы try_read_for и try_write_for. RefCell как бы не предназначен для многопоточных приложений.
>try_write_for
Нашёл в другом крейте https://docs.rs/lock_api/0.3.3/lock_api/struct.RwLock.html
спасибо, попробую. Хотя можно и мой костыль под дефолтный RWLock переписать - его тоже нагуглил.
Это и есть parking_lot, точнее его дочерний крейт (в самом parking_lot'е стоит алиас type RwLock<T> = lock_api::RwLock<RawRwLock, T>;). Напрямую lock_api использовать не надо.
https://docs.rs/parking_lot/0.10.0/src/parking_lot/rwlock.rs.html#89
> Хотя можно и мой костыль под дефолтный RWLock переписать - его тоже нагуглил.
Твой костыль очень хуёв в плане производительности и задержки. Мало того что идёт переключение контекста каждый раз при засыпании треда, так и при освобождении ресурса функция может возвратить результат не сразу. RwLock со встроенными таймаутами в разы лучше. В std поддержки таймаутов в RwLock'е нету, но если захочешь добавить в любом случае будешь изобретать похожий велосипед. Лучше возьми готовое.
Ах, да. Чуть не забыл. У тебя напрочь отсутствует fairness. Что значит если непрерывно идёт много читателей, то поток на запись просто может быть навсегда заблокирован.
Точнее не навсегда - у тебя ж таймауты. Но запись просто никогда не будет успешной.
Спасибо, боярин, и правда пошустрее стало (вроде). Не то, чтобы оно особо тормозило, но на обработке очереди 4 тыка по 5 raw снимков в серии ощутимо лагало - сейчас немного лагает.
{
"componentName" : "position",
"value1" : "i32",
"value2" : "i32",
"value3" : "i32"
}
Далее мы должны создать по образу и подобию блять структуру статического размера, а потом грамотно уложить её в массив, чтобы его не распидорасило по всему heap'у.
Если бы это делалось сразу в коде, то ничего сложного, просто объявляем структуру с полями value1..3 и всё. Но проблема в том что я не знаю как это сделать всё в рантайме. То есть мне надо в рантайме создавать типы определённых компонентов, и потом соотвественно эти компоненты заполнять. Там будут лежать только фиксированные по размеру инты всякие, или же ссылки которые ведут уже в кучу (но они относительно не так часто будут использоваться).
Надеюсь я понятно пояснил.
Ну я думал над чем-то подобным, но мне показалось что мой пример какой-то всратый и потенциально проблемный. Что можно просто взять, объявить одну структуру допустим, которой мы просто укажем внутреннему массиву размер исходя из того сколько в этом типе все совокупно байт будет (ну допустим на 3 i32 у нас уходит 96 байт.), а также создадим "дешифровку" этих байтов (Передаётся коду который будет работать с определённым типом компонентов). Потом создадим экземпляр как ты сказал хэшмап или чего-нибудь пошустее (динамический массив тут норм будет.) и запихивать уже эти экземпляры.
У меня тут просто возникает вопрос, как это всё дело будет укладываться в памяти, потому что с этими компонентами будет очень много тяжёлых операций, и это может обосрать всю производительность. В идеале конечно чтобы было вот так как на пикрелейтеде. Ну то есть чтобы они прямо вот так штабелями нахуячены были прямо в памяти. L1 кэш, все дела...
Извините за такие ебанутые вопросы, просто я совершенно не знаю во что там и как Раст превращает процессы укладки данных в памяти.
Алсо ХэшМэпы не шибко медленные?
Да ну чего ты, ну. Не обращай внимания на то как я выражаюсь, а на то что донести хочу.
Такой структуры в расте по-моему нету. Есть только tagged enum, но там каждый элемент будет иметь размер самого большого элемента. Нужно городить самому с ансейфами, вот кое-что сделал (только не гарантирую, что всё сделал правильно и там нет UB): https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0797858ab4cc20d8a42cc8669b81d2d9
Новый размер массива вычисляется так:
let new_size = self.bytes_size + size * 3;
т.е. берётся размер добавляемого элемента и умножается на 3. Можно изменить по своему вкусу.
Но есть несколько недостатков:
1) Из-за отсутствия стабильного const-модификатора, приходится при каждом вызове вычислять Layout::new для TypeId и usize. Можно исправить с помощью lazy_static.
2) Раст не гарантирует отсутствие коллизий для TypeId (что на самом деле пиздец тот ещё). Можно вместо него использовать свои хеши, вычисляемые в компил-тайме и в которых гарантированно отсутствуют коллизии.
3) Из-за отсутствия стабильных unsized rvalue, в таком контейнере лучше не хранить элементы с деструктором. Либо он будет вызван сразу после добавления в контейнер, либо не будет вызван никогда (как сейчас). Не решается никак, лол. Впрочем даже с unsized rvalues если не выполнить итерацию по всем объектам, то деструктор не-итерированных объектов не будет вызван (по идее решается стабильным ABI и апкастом в трейты, но такого даже в планах нету).
Ну спасибо, буду разбираться. Вообще я просто хочу попытаться создать годную реализацию ECS с возможностью создания систем и компонентов в рантайме.
https://en.wikipedia.org/wiki/Entity_component_system
В общем подумаю ещё как это можно без ансейфа сделать хитро. Кстати не вдуплил зачем он на 3 умножается.
Ещё можешь через кодогенерацию нагенерить все возможные типы, задать для них хранилища в главной структуре и матчилки в методах для складирования/извлечения.
Т.е., берёшь какой-нить темплейтный движок, пишешь кодогенератор, присобачиваешь это всё к build.rs и вперде.
Ну и идея конечно. А можно просто создать одну структуру, внутрь засунуть ей просто массив байтовый, или может другой метод хранения нетипизированной информации, (допустим у нас будет 256 байт максимум для каждого компонента), а уже потом в него кастить инты всякие, или ссылки допустим превращать в байты. Но вопрос встанет - какие вообще будут расходы на чтение и редактирование по сути своеобразных POD из этой структуры.
>>12804
Ебическая сила какие они быстрые. Но опять же если туда не прикрутить внятную возможность именно в рантайме новые типы создавать (я все данные, большинство систем подцеплять думаю их луа и жсонов каких-нибудь), при этом не городить еботню какую-то, то эти либы в пролёте.
>>12803
Ну извини, не умею внятно объяснять другим людям наверное.
> Кстати не вдуплил зачем он на 3 умножается.
Просто так. Чтобы не вызывать realloc при каждом добавлении элемента. Я ж сказал, что тюнить надо под задачу. Тут в отличии от стандартного Vec'a нельзя предсказать размер последующих данных.
>>12818
> именно в рантайме новые типы создавать
Такого в расте не будет. Максимум будет как работа с нетипизированными данными функциями уровня `read_u32(&mut self, is_be: bool) -> Option<u32>` и проверочкой после каждого чтения. Разве что в расте можно обойтись без копирования данных, оставляя в структуре ссылки на слайсы с байтами. А вообще мне кажется ты что-то делаешь не так. Неужели нельзя каждый компонент описать до компиляции и всю ёблю с десериализацией оставить тому же serde?
Возможно всё-таки придётся создать все компоненты непосредственно самим кодом, оставив просто фичу-возможность с помощью жсонов использовать какие-нибудь заранее слепленные-шаблонные компоненты, которые уже просто своими заплоняешь данными и вписываешь ему id. Нда, вроде задача не то чтобы сложная, в голове-то блядь решение представить можно, а язык не позволит такие кульбиты вытворять. Вот так пиздос конечно. Но всё равно спасибо аз помощь.
>нельзя предсказать размер последующих данных.
НУ вообще предполагалось что типы копонентов инициализируются 1 раз (под инициализацией понимается сборка самих полей, считка того сколько получилось памяти, сохранение где нибудь инструкций как это расшифровать, и собственно создание самого vec под этот тип компонента), и после инициализации они по-сути свой размер и поля право менять и имеют.
Тебя просто сложно понять. Ты хочешь жсоном декларативно описывать компоненты, так? Но что ты с ними собираешься делать? Как-то их преобразовывать? А описание преобразования тоже будешь описывать в жсон-файле с компонентом? Тебе тогда тут целый интерпретатор твоего жсона надо будет делать. И раст тут не при чём, ты ни в каком языке подобное не сделаешь, чтоб работать с незнамо какими данными.
> собственно создание самого vec под этот тип компонента
Так у тебя в массиве будет храниться один тип компонента. Я-то думал ты в массиве хочешь хранить разные компоненты и потому нагородил свой костыль, который позволяет складировать в себя разные типы (сохраняя их в TLV-виде), а потом их динамически преобразовывать при чтении обратно.
> именно в рантайме новые типы создавать
В чем сложность? Все компоненты заранее известны, собрать произвольную энтити на основе жсона нет никаких проблем.
>Тебя просто сложно понять.
Да я сейчас со стороны посмотрел и подумал что я и правда какой-то поток сознания вывалил. Следующий раз постараюсь более последовательно задачу расписывать.
>>12921
>о что ты с ними собираешься делать? Как-то их преобразовывать?
Только создавать экземпляры типа и помещать в массив.
>Так у тебя в массиве будет храниться один тип компонента.
Да, для каждого типа будет создавать отдельный vec. То есть внутри этого массива они будут одинаковы. Давай опрпобую ещё раз.
Есть тип компонента, он допустим магическим образом определяется в рантайме, и для этого типа также создаётся vec-массив. Для каждого типа компонента массив свой.
После того как тип компонента создан, его поля изменять нельзя, а можно менять только значения этих полей.
>>12933
В том то и дело что я намерился создать расширяемый за счёт скриптовых языков и таблиц данных (LuaJit, Json, TOML) движок. То есть возможно создавать компоненты и системы в рантайме.
Он хочет, чтобы оно у него хранилось ровно разложенным по полочкам. Вот только размер полочек, как и размер хранимых данных ему заранее неизвестен. Вот, он думает, ща как создаст структуру в рантайме с в рантайме вычесленным размером, как начнёт её складировать в заранее отведённый вектор (?), так благодать на него и польётся.
Т.е, его вопрос больше про оптимизацию. Чисто технически, полагаю, у него отработало и что-то вроде того, что на пике.
Даже подозреваю, что решение его задачи всё-таки есть в каком-то крейте.
Не совсем так конечно, подразумевается что эти структуры будут не векторы хранить со стандартными а сами будут в векторе, и хранить эти типы как обычно. Ну видимо я и правда идиотскую задачу задал не знаю.
>заранее отведённый вектор
Имеется ввиду что для каждого вида компонента свой будет вектор. и создаваться он будет как раз на инициализации видов компонентов создаваться и определяться.
> Только создавать экземпляры типа и помещать в массив.
Ты не можешь создавать экземпляр того, что не существует на момент компиляции. Что мешает сохранять чисто данные? Создай хэш-карту HashMap<TypeTag, Vec<u8>> и в массив сохраняй в виде `длина,данные`. Где длина - фиксированный размер в байтах, а данные - непосредственно байты. А преобразование туда/сюда уже делай на уровне FFI хоть на расте, хоть на луе.
> в виде `длина,данные`
Впрочем если длина фиксирована, то её можно и не сохранять в массиве, а хранить непосредственно в тэге. Т.е. в массиве будут чисто данные друг за дружкой, а вот сами поля данных уже можно упаковать через TLV (тип,длина,данные), тип и данные будут идти через FFI языку и там уже преобразовываться в нужную структуру.
Во! Действительно годное решение, наконец-то. Нижайший поклон. К слову, а поиск в этих хэшмапах и преобразования туда/сюда, много ли с них накладных расходов будет? Потому что чтение этих компонентов нужно будет делать быстро-быстро блядь.
Да, это годное решение. Спасибо.
Ну если совсем беспокоишься о производительности, то можно вместо хэш-мапа использовать тот же вектор (или массив фиксированного размера) просто создать глобальный счётчик и при создании новых данных добавлять в глобальный вектор данных новый пустой вектор с компонентами (который и будет по адресу счётчика) и сохранять счётчик в самом теге, который и использовать для нахождения данных. Создания нового компонента станет медленней, а вот доступ быстрее.
И да, вектор в этом плане скорее всего совсем не подойдёт, ведь его придётся упаковывать в RwLock, плюс он может реаллоцировать а значит создание нового типа будет тормозить чтение любого компонента.
Ну опять же, если типы будут создаваться только в 1 момент программы (на запуске), будет ли это проблемой? Сначала создали типы компонентов, потом заполнили экземплянами этих типов, а потом ебись оно всё в рот.
Тогда и реаллокации не будет, я правильно понимаю?
> они создаваться будут только на запуске программы
Тогда вектор будет идеален, да. Доступ фактически будет только O(1) на поиск контейнера типов. А как ты собираешься доставать данные? По индексу? Будешь ли ты их удалять? Преобразование в основном упирается в порядок байтов. Впрочем если луа использует машинный endianness, то для преобразования четырёх u8 в u32 достаточно вызвать mem::transmute (который вообще ничего не делает в рантайме) и просто сказать расту что это ссылка не на четыре байта, а на один u32.
> А как ты собираешься доставать данные?
И, кстати, что насчёт многопоточности? Я бы задумывался об оптимизации фрагментации памяти уже после оптимизации доступа из разных потоков. Потому что первое увеличит потребление памяти, а второе уже может дать значительные лаги.
>А как ты собираешься доставать данные?
По индексу, да.
>Будешь ли ты их удалять?
Буду, ну из можно просто освобождать если что, допустим создав в менеджере вектор свободных индексов.
>Преобразование в основном упирается в порядок байтов.
Тут будет только преобразование байтов в их формат который и имела информация до превращения в байты. А, ну ещё адреса указателей или что-то подобное. ПОтому что нужно будет в компоненты ещё строки пихать, или массивы (допустим компонент storage, который хранит массив id ентити.)
Не совсем. У tagged union все типы должны быть известны на момент компиляции, в TLV-формате можно хранить типы, создаваемые в рантайме.
Я нигде сам не нашёл, поэтому спросил тут, может кто видел-знает. Если такой вообще не ведётся, наверное придётся делать самому
Просто я в обучении часто люблю диаграммки простые составлять, как бы деконструировать по небольшим и легко понимаемым-запоминаемым примитивам одну тему. Предполагаю что подобного врятли можно найти в Rust, поэтому думаю - может и самому попробовать составить. Там будет всё по темам и зависимостям. Допустим Операторы и выражения, Типы данных и функции, визуальное отображение того как зависимость можно работать, краткое описание основных STD и прочие вещи. Эта памятка не будет на полноту информации претендовать, но я считаю что для того чтобы что-то быстро вспомнить или просто систематизировать начинающим инфу будет самое то. Но я пока сам только изучаю, поэтому мне интересно что вы скажете и чего добавите. Через некоторое время как мне инфы или идей накидают (или не накидают, кто знает) я начну делать её.
Почему раст не взлетает? И когда взлетит по-вашему? ЯП-то годный в плане концепции. Представьте себе мир без уязвимостей на низком уровне - это же просто охуенно. Бтв, даже если в ансейфе есть переполнение, его очень трудно эксплуатировать, так как лэйаут памяти программы не позволяет это сделать также, как в прогах, написанных на си и крестах. На мой взгляд, через лет 10-15 весь лоу лвл будет порабощен растом, целый пласт низкоуровневой безопасности канет в небытие и станет частью истории. Ну а Си и кресты уйдут на заслуженный отдых, языки явно несовременные и свое они уже отжили.
Клянусь всем чем можно, что я не троллю. Но я не понимаю почему эти языки нельзя считать несовременными?
Они держут высокий рейтинг в TIOBE только по одной причине - на этих япах написано ОХУЕТЬ как много легаси программ. Просто О Х У Е Т Ь как много. Но эти языки имеют проблемы, причем серьезные. Кресты набрали кучу стандартов и сейчас в мире есть только несколько людей, которые реально могут сказать, что они ЗНАЮТ кресты. И это разработчики известных компилятором для крестов. Все. Остальные кресты не знают, их НИКТО не знает. Си - вообще отдельная история. Этот язык - сама по себе уязвимость.
Почему раст, имея бинарную неуявимость (хорошо отдебаженный код на расте практически невозможно взломать, только если будут логические ошибки, которые найти ОЧЕНЬ трудно, ошибки работы с памятью, которые детектятся санитайзерами и фаззерами, идут лесом), не может заменить их в нише лоу левела? Напишут пару ОС на расте, они наберут популярность и все.
Имхо люто играет синдром утёнка. Но при этом востребованность всё таки формируют бизнез компании, а им пока что далеко не всем есть что в расте ловить. Годных либ раз-два и обчёлся, а те что есть написаны с использованием того же ансейфа (ну не могут люди просто так изменить своё мышление и перейти с байтоёбства на более общие архитектурные решения или методы)
Конечно это только моё мнение, самому интересно как чзцк будет развиваться.
Но опять же не стоит забывать про его сложность. Я вот только сейчас вкатываюсь и понимаю что материалов которые бы конкретно и поэтапно подавали инфу нету. Тех двух книжечек явно недостаточно потому что я читаю и у меня глаза на лоб лезут нахуй от того как автор вроде рассказывал сначала про типы данных а потом залез в макросы и модули при этом ничего не пояснив, мол смотри читатель блядь как я умею. Понятное дело что там одно за другое цепляется, но блять, без нормального разделения и структурирования такой язык как раст проглотить будет ебейше тяжело.
>>17849
Тут я к слову описал что хочу сделать. Думаю такой метод подачи не только мне зайдет.
Можно сразу начать с того чтобы описать основой синтаксис и как и почему блять скобочки точечки эти нахуй выставляются, почему где то используются круглые, а где то <>. И всё это без описания самой std поначалу. Чтобы какая-нибудь хуйня типо Box<[Option<mut Container>]> не погружала неофитов с тантрум, а была вполне хотя бы относительно понятна что тут с чем пытается что сделать.
О, благодарю! Вот из этого можно памяток наделать. Хотя возможно всё равно придётся как-то систематизировать всё это дело
ide используй. Там оно подсвечивается и автовыводится.
Вообще, скобочки и точечки не самое сложное в расте. Я, например, долго привыкал к тому, что нельзя просто взять и вернуть указатель (&), даже если ты сам результат получил уже в виде указателя. А потом, чё-т, раз и привык.
Ну ты смотри на сложность которая вызывается от привычки (индивидуальная для каждого) и сложность которая вызывается от самой комплексности какой-либо вещи. Если в Расте очень много пересечения функционала и возможностей (как собственно и должно быть не спорю, но на понимание языка это влияет сильно), то это дико замедляет процесс понимания, потому что башка на плечах не в состоянии всё это дело грамотно распутать и разбить на удобоваримые кусочки-концепции. И вот тут у меня взорвалась жопа. Сейчас пока разберусь сам насколько смогу, потом надо реально подумать над тем как это всё дело переварить и высрать в виде понятном.
Поставь ide и сразу пиши, не еби мозг. Я поначалу пытался через vim с одной только подсветкой его освоить - знатно охуевал. Потом накатил-таки идейку и процесс пошёл.
Подозреваю, что и ты также мучаешься.
А может и не быть. Если не пофиксят.
Что сразу "не еби мозг"? Будто тебе лишний раз боязно разобраться более фундаментально в том что ты делаешь (или просто дед который не чует муки нюфань уже). VS Code вместе с дебаггером ЛЛВМ я давно установил уже, но я хочу сразу заложить базу понимания какбе.
>Тех двух книжечек явно недостаточно потому что я читаю и у меня глаза на лоб лезут нахуй от того как автор вроде рассказывал сначала про типы данных а потом залез в макросы и модули при этом ничего не пояснив, мол смотри читатель блядь как я умею.
Два чаю. Чуть не обосрался, пока не понял, как работает хендлинг ошибок с помощью комбинаторов в rust-by-example.
Энивей, после 3 лет пердолинга в плюсах, лично для меня раст - это охуеннейший язык.
Изучаю книгу Программирование на языке Rust от O'Reilly
Будут советы, кроме очевидного, что раст не нужен и денег мне не принесет. Я для развития как личности
Бля, sed -r "s#принесет\.#принесет\?#"
Вообще как я понял основная суть Раста в том, что он пытается занять нишу крестов, но при этом сам подход к разработке ПО довольно сильно отличается от плюсов, это надо понимать. Потому что я уверен что первое время (а может и второе) раст смогут осилить только как раз крестовики, и притащут туда свои знания и методы работы, превратя код в клубок ансейфа и попыток в наследование лол. Я конечно сам пока в процессе постижения, но уже явно видно что у Раста другой путь решения задач. Часто придётся пересматривать саму постановку задачи и методы её выполнения, чем начинать писать костыльный и небезопасный код, что по привычке C/С++ очень даже поощрял (неопределённым поведением, ага.)
Если хочешь писать нормальный код на Rust, идею байтоёбства желательно погасить, потому что она будет постоянно подталкивать тебя на нарушение правил, и весь основной сок безопасности в Rust просто будет невилирован
>раст смогут осилить только как раз крестовики
да лан те, я вон, кресты не смог (не захотел) осилить, сразу на раст полез.
А те крестовики, которые идут в раст, они, как раз, стараются быть святее Папы Римского, из-за комплекса новообращённых. Как нигеры в Африке головы друг другу режут, доказывая, что ислам/христиантсво самая миролюбивая из религий, так и растовики затравят кого угодно за лишний ансейф (не путать с ансейфами в ffi коде и всякой лоу-лвл работе с железом - они не лишние).
Ну не знаю, сдаётся мне и те и те там есть в примерно схожих пропорциях. Одни травят других.
Я вот лично вообще никакие языки не знал, Сначала кресты пытался осилить, вроде начало получаться но потом дропнул потому что пришлось заниматься другими вещами. Потом вернулся но уже на Го, мне он показался минималистичным и прямо то что надо, только потом просёк насколько он медленный по сравнению с крестами и пошёл дальше искать. Вот нашёл Раст, вроде всё устраивает.
> затравят кого угодно за лишний ансейф
Одна из проблем это популярность актикса. То есть раст позиционирует себя сейфовым, при это одна из самых популярных либ не особо сейф. Отсюда и предъявы.
Ну вот и ЧТД, потому что толковые программисты которым было интересно двигать Раст и имеющие опыт написания серъёзного ПО работающем на низком уровне, скорее всего вышли-то из крестовиков, а там у них выдрачивать байты из компа это привычка, потому без ансейфов им очень неудобно. Ну как бы блядь, не скажу что это плохо, это наиболее вероятный и логичный исход скажем так. Конечно исправить его можно только собрав группу матёрых спецов по Расту (вопрос откуда таких наколдовать) которые бы сделали тот же самый велосипед, но уже без ансейфа. Выглядит как аутизм и какая-то ебанутая игра политическая.
https://github.com/actix/actix/search?q=unsafe&unscoped_q=unsafe
Хотя так посмотришь, вроде не шибко много-то его. Или может я чего-то недогоняю
Именно, что там ансейф был использован в том месте, где без него вполне можно обойтись. Даже так: на базе ансейфа был сделан костыль, чтобы "обмануть" конпелятор.
Я вот сейчас vulkano использую и периодически в него заглядываю - дак там чем глубже в код, тем толще ансейфы - а иначе в работе с железом (не совсем, но железо накладывает долю неопределённости) никак.
Кстати интересно знать сколько эта обётрка отжирает по перфомансу.
от нативного вулкана.
тоже програть игрульечку хочеш?
Не, у меня больше по машинному зрению и вычислительным шейдерам интересы.
игрульку вот прям на вулкане с нуля - я бы не стал. Оно вроде и заманчиво, а на деле пуд соли съешь и 1000 раз пожалеешь, что не взял готовый движок. Лучше сосредоточиться на сюжете/графоне/геймплее.
Ну смотря конечно какую игру делать. У меня как-то давно загорелось в жопе сделать рогалик где бы механики всякие и симулятивность сука ух бляя. Я полтора года носил эту идею в голове думал ну блять тяжело наверное такое воплощать сука! Временами выливал свои мысли и решения геймплейные алгоритмические о том как те или иные вещи лучше делать, но пиздец, идея до сих пор не отпала, дерёт сука голову и всё, ну я подумал ну хуй с ним будем делать блядь. Вот сейчас учу. решил движок с нуля писать (ну може какие либы подтяну типо bearLib) потому что мне нужен ECS с возможностью рантайм компонентов, мне как раз выше аноны помогали с этим.
>parameter pack
не знаю, что за зверь, но по звучанию похоже на trait в расте. Или объясни подробнее.
1) Ты не там ищешь. Нужно искать втрепе actix-net: https://github.com/actix/actix-net/search?q=unsafe&unscoped_q=unsafe
2) Ансейфов там мало, потому что они используются в фундаментальных типах, которые потом используются везде. Например вот эта функция нужна чтобы ебать borrow checker в рот: https://github.com/actix/actix-net/blob/631cb86947cb2a3d2ccce2db59cf8e6d6fc23680/actix-utils/src/cell.rs#L40 и помечена она как безопасная (сам тип является аналогом UnsafeCell из стандартной библиотеки, только где все unsafe-функции помечены как безопасные), хотя может вызывать UB.
> вот эта функция
Упс, ошибся. На одну ниже: https://github.com/actix/actix-net/blob/631cb86947cb2a3d2ccce2db59cf8e6d6fc23680/actix-utils/src/cell.rs#L45
> pub(crate) unsafe fn get_mut_unsafe(&self) -> &mut T {
Хм, хотя её уже пометили как ансейф (последний раз когда смотрел она была безопасной). Вот что значит уход говнодела. Сразу качество софта повышается.
Ну бля, почему сразу говнодела. Без него актикса вообще не было бы, хуёво конечно что он такой UB код высрал, но его всяко теперь можно исправить без особых заморочей чем всё писать с нуля.
https://en.cppreference.com/w/cpp/language/parameter_pack
Я думал в раст перекатываются только бывшие крестовики, которых заебал бардак.
Можно. Берёшь какую-нибудь regex либу и пишешь. В std работы с регексами нет, только со строками.
Не какую-нибудь, а вполне себе оффициальную: https://github.com/rust-lang/regex
Правда если он начнёт использовать мега-фичи регулярных выражений, вроде lookahead и lookbehind, то тогда уже придётся переходить на биндинги для PCRE.
>мега-фичи
>lookahead и lookbehind
Дожились, это стало мегафичей. обычная и нужная вещь, особенно когда у тебя есть свое экранирование по бэкслешу
Теперь все что не реализовано превращается в "ненужно" как у гоферов?
> и кривое ООП
В расте ООП вообще нет. С одной стороны мне после жавы (где ООП в основном используется в виде "один класс наследует интерфейсы") неудобств не предоставило, но с другой из-за отсутствия GAT [1] и отсутствию impl Trait [2] в ассоциативных типах (вторая фича по сути не даёт функциям из трейтов возвращать анонимные объекты, соответствующие какому-то трейту, а первая не даёт вместо со второй фичей возвращать трейт, который хоть как-то зависит от входных параметров) очень неудобно. В жяве я привык всегда возвращать интерфейс, а какой класс там на самом деле его имплементирует - скрывать, а в расте пока это невозможно.
Надеюсь обе эти фичи в этом году завершат. Они обе необходимы для нормальных асинхронных функций в трейтах (потому что там та же проблема - возврат анонимных типов, о которых вызывающему будет известно только что они имплементируют трейт Future).
[1]: https://github.com/rust-lang/rust/issues/44265
[2]: https://github.com/rust-lang/rust/issues/63063
> Теперь все что не реализовано превращается в "ненужно" как у гоферов?
Я честно не знаю реализовано оно в го или нет. В крейте regex но точно не реализовано, потому и предупредил.
Есть Box<dyn Yoba>. Просто жава тебе не рассказывает про цену возвращения интерфейсов, а раст прямо в ебло запихивает боксами.
Я в курсе. Но я и перешёл на раст потому что хочу перформанса (в том числе ценой меньших аллокаций и работой напрямую с объектами без vtable). Насчёт dyn я в курсе. Например я его использую в одной рекурсивной функции. Сначала пытался использовать impl, но раст выдал мега-ошибку, потому что сам тип тоже рекурсивный и после 128 (по-моему) инстанциаций там была ошибка с гигантским Type<..., Type<..., Type, ..., ...>>>. Но и всё равно обошлось без Box - просто передавал ссылку &mut dyn Type.
Как я понял, это аналог args/*kwargs гвидона.
Есть RFC https://github.com/rust-lang/rfcs/issues/376
А пока вот так: https://doc.rust-lang.org/rust-by-example/macros/variadics.html
>го
1. Пока что ниша го куда уже, чем потенциально у раста, хотя в этой самой нише он (го) довольно прочно закрепился. Раст также широк, как гвидон, и даже чуть шире (для машобчика только биндингов маловато)
2. Периодически проплывают новости об отказе от го в пользу раста, но не наоборот (может я не те новости читаю)
Go.NET?
>Kotlin GDNative bindings
Спасибо конечно но нах оно когда я про Rust GDNative bindings прашиваю
>2014
>This RFC introduce variadic tuples, and API to handle tuples with an arbitrary arity.
>2019
Понятно.
> GAT
> в этом году завершат
Я искренне завидую твоему оптимизму IIRC его же там взялся делать только один чувак, который потом сказал "ну нахуй". Хорошо бы хоть const generics запилили.
Немного невдуплил зачем нужен Box<> вообще. Понятное дело что Option<> решает важную проблему (которую зачем-то намеренно создали), но не понятно нахуя бокс. вроде как любые структуры, массивы и векторы и так выделяются в куче.
Box - это умный указатель, который не может быть скопирован. В основном используется там где ссылки использовать невозможно (например из-за отсутствия GAT и unsized rvalues) либо чтоб не нагромождать структуры шаблонным временем жизни и вместо
struct A<'a> {
b: &'a B,
}
написать просто
struct A {
b: Box<B>,
}
>>22024
> Не все.
Массивы наоборот всегда выделяются на стеке. Чтобы заставить раст выделить массив в куче как раз и надо использовать Box. И с этим у раста есть проблемы, потому что он вместо того чтобы сразу сделать массив в памяти, сначала делает массив на стеке и потом копирует его в память: https://github.com/rust-lang/rust/issues/53827 Особенно весело выглядит с MaybeUninit, когда со стека в память копируются неинициализированные данные, а стабильного способа создать неинициализированный массив в памяти до сих пор нет: https://github.com/rust-lang/rust/issues/63291
Да, хуйню сморозил точно, но всё ещё не понятно нахуя это дело выделять в боксы. Это допустим нужно для того чтобы со всякими структурами играться? ну инициализировать сразу походу пихать их в коробки и в массив, кортеж или хуй пойми куда. Не доходит что-то.
Вот, спасибо за пояснения, но пока не совсем понял что такое
GAT и unsized rvalues до конца. Это как-то связано с теми данными и переменными которые во время компиляции устанавливаются?
>Массивы наоборот всегда выделяются на стеке.
Интересно насколько это на самом деле больная проблема. Просто мне кажется что обычно когда мы ходим выделить массив в куче, то там лучше применить просто вектор сразу чтобы лишний раз не ограничиваться. Хотя могу ошибаться.
> а стабильного способа создать неинициализированный массив в памяти
Ну хотя я конечно приврал. Можно напрямую использовать аллокатор
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5b115ddabc5b0f6eb5f12817a345672e
Unsized rvalues нужны чтобы можно было на стеке создавать переменные неизвестные на момент компиляции размера (ну и так же передавать их в функции и возвращать). Например dyn Trait - это переменная с неизвестным размером, потому что неизвестно какого размера будет структура, имплементирующаа trait и какого размера будет vtable. Потому dyn Trait можно передавать в (и возвращать из) функций только в виде ссылки (&dyn Trait) или внутри указателя (Box<dyn Trait> или (A)rc<dyn Trait>). Тоже самое касается слайсов - массивов, где количество элементов вычисляется в рантайме.
GAT нужны чтобы внутри трейта можно было создать генерики, которые будут зависеть не только от шаблонных параметров самого трейта, но и от параметров функции где они используются. Например чтобы функции из трейта могли возвращать структуры с шаблонным временем жизни, как здесь: https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=14b4218a38b94f3b4cbf45d8d8a8c464 Сейчас нужно использовать умный указатель для этого: https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=37029a81774effb1c091546d564c98d3
> Но мы же можешь проинициализировать массив структур допустим через Option<MyStrcuct> как None, а потом уже запихать в него в рантайме что надо или просто в другом куске кода?
Для этого есть MaybeUninit: https://doc.rust-lang.org/std/mem/union.MaybeUninit.html но опять таки функция assume_init является небезопасной, потому что компилятор никак не сможет проверить ты точно всё инициализировал правильно или нет.
Да уж, с растом приходится от души так перепахивать свои подходы к написанию программ. Ну может оно и к лучшему, раз от этого более безопасный код получается.
Впрочем ты можешь использовать Option для инициализации, но у него есть пара недостатков:
1) Он может занимать больше места, потому что должен хранить в памяти ещё и состоянии - инициализирована переменная или нет.
2) Доступ не нему будет всегда медленней, потому что при каждом запросе ко внутренней переменной он будет проверять инициализирована она или нет.
Ну да, это может быть дороговато.
>хотя его использование не может быть UB, поскольку любое значение корректно для u8
Значение неинициалированного u8 - это undefined, оно не корректно. С т.з. ЛЛВМ.
Теперь (в 99% случаев) не надо ебаться с прерываниями, синхронизацией и прочим говном. Можно просто все прерывания оборачивать в асинхронную функцию и работать как с сихнронными методами. Жалко что для работы в стабильной версии надо ждать пока https://github.com/rust-lang/rust/pull/69033 дойдёт до нее. Если успеют запушить в версию 1.43, то через пару месяцев будет в стабильной. Иначе ещё пол-года ждать.
Фигурная скобка очень секси.
На связи крестовик, пишущий крипту на работе.
Стоит ли пробовать раст? Что сложного будет? Говорите порог вхождения высокий, что именно сложное?
Я попробовал чуток, мне понравилось что есть карго и нормальная поддержка модулей.
Какие подводные короч?
Представь, что ты всю жизнь дрочишь себе рукой. Дрочишь, дрочишь, уже привык, даже не кончаешь через пару секунд. И вдруг у тебя появляется девушка! Приходится переучиваться, учиться двигать бёдрами, а не рукой, туда-сюда, хуяк-хуяк. И охуеть как сложно, и ТНН, и хочется просто взять всё опять в свои руки.
Вот такие же подводные и в расте. Он охуенный, но твоей фирме не нужны твои дети, потому что она не хочет оплачивать тебе отпуск.
Ну и заебёшься всё расписывать, потому что раст не может тебе превратить i32 в usize, когда ты пытаешься достать что-то из массива через индекс. Это круто, примерно как TypeScript по сравнению с жаваскриптом, но макаки часто не могут осилить TS.
> И вдруг у тебя появляется девушка!
И у этой девушки одна сиська. Не то чтобы мешает основному действу, но неприятно, особенно когда пытаешься что-то помять рукой в этом месте, а там ничего нет. А родители девушки уже который год кормят обещаниями, что скоро пришьют и вторую и она станет полноценной.
Да не, сисек у неё две (системный же язык, можно что угодно написать, надо только немного хуй поднять и через ногу плюнуть). Вот нос с горбинкой и размер у сисек всего первый, но обещают скоро исправить операцией.
>системный же язык, можно что угодно написать, надо только немного хуй поднять и через ногу плюнуть
То есть сиська как бы есть, но ее нужно пришивать своими руками
Как миниум из-за отсутствия const generic там нельзя написать кучу абстракций (попробуй например передай в println! массив с более чем 32 элементами). Ну и плюс мегаубогий трейт Read, который используется повсеместно и в который нельзя передать неинициализированные данные без UB. Даже стандартная библиотека признаёт что использует UB (да и все кто хоть как-то заботится о перформансе так делают). Слава богу асинхронную версию Read уже пишут специально затачивая под неинициализированные массивы.
Лол, а чем этот сладкий хлебушек от майкрософтов лучше?
Зачем кушать хлебушек, если можно на чистом жиэс писать? Никогда не понимал эти тайпскрипты, пурскрипты, кофескрипты...
Конкретно тайпскрипт лучше за счёт строгой типизации. Позволяет часть ошибок вывести из рантайма в компил-тайм, ну и в целом крупные проекты легче делать со строгой типизацией (особенно если есть проблемы с тщательным документированием каждого метода и написанием тестов).
> Стоит ли пробовать раст?
Однозначно стоит. Даже если не подсядешь, вынесешь для себя что-то полезное назад в плюсы.
> Что сложного будет? Говорите порог вхождения высокий, что именно сложное?
It depends. Смотря что ты уже умеешь/знаешь. Думаю после плюсов будет очень хотеться обмазаться указателями, а нельзя. Субъективно для меня было самыми сложными вещами (по нарастающей) - лайфтаймы, различие между (fn, Fn, FnOnce, FnMut), HRTB, ну и процедурные макросы.
Вообще самая большая проблема - надо начать думать немного по-другому, и строить программы немного по-другому. Но это справедливо при переходе на любой другой язык почти. Первое время будет бомбить как у анона выше
> потому что раст не может тебе превратить i32 в usize
но потом ты поймешь, что это абсолютно разумные ограничения.
Ну и не хватает иногда каких-нибудь возхможностей языка, приходится ждать, пока сделают/стабилизируют. Но думаю тебе не привыкать, C(++) изменения лет по 10 делают.
Так я и не говорил, что неразумные, я эти ограничения сравнил с TS vs JS, если ты не заметил. Но не все макаки могут в TS, как я уже говорил.
>эти тайпскрипты, пурскрипты, кофескрипты...
Тайпскрипт - это жс со статическими типами.
Пурскрипт - это язык вроде Haskell, только трнаслируется в жс. В отличие от Elm, там есть монады и вся остальная дрочь, но на нём никто не пишет, потому что сложна.
Кофескрипт - это был такой синтаксис сахар, придуманный рубистами, потому что обычный жс для них был недостаточно гибок и эстетичен. Не актуален начиная с выхода ES6.
Инбифо: сорта говна
> Fn, FnOnce, FnMut
С этой хуйнёй больше всего бесит, что сейчас в расте они являются МАГИЕЙ и по сути встроенными вариадик генериками в языке. Отсюда вытекает то, что эти трейты невозможно имплементировать в свою структуру - только использовать синтаксис замыканий.
Как я пригорел с этой хуйни, изучая комбинаторы раста - просто пиздец. До последнего не хотел гуглить, но все же.
Единственное, с чего жопа на марс улетела за всё время изучения языка, наверное.
Миссажа, соре.
Как делаю я:
1. Кодишь на языке, как если бы это был Си, только с хитрым борроу-чекером
2. Постепенно начинаешь осваивать фичи, про которые что-то слышал, но боялся применять на этапе 1. Трейты, дженерики, лайфтаймы.
3. Постепенно начинаешь осваивать фичи, про которые что-то слышал, но боялся применять на этапе 2. Замыкания, dyn трейты, процедурные макросы.
..
N. Постепенно начинаешь осваивать фичи, про которые что-то слышал, но боялся применять на этапе N-1.
как делаешь ты, и многие другие аноны: выучить ВЕСЬ язык, прочитав БОЛЬШУЮ, сука, книжку.
Бля, ну хуй знает, кто из нас прав, может быть даже я не прав. Но мой путь полегше будет.
Жопа начинает гореть примерно на втором шаге когда начинаешь натыкаться на сообщения компилятора, что эта фича экспериментальна и вообще идите нахуй.
У LLVM только чтение неинициализированных данных - UB. В расте даже ссылку брать нельзя - сразу UB (можно брать указатель). А трейт Read ничего кроме ссылок не принимает. При том есть те, кто такое поведение защищает и считает, что обнуление памяти перед использованием массива должно быть обязательным (как в языках уровня жявы), а все кто не согласны могут не использовать std.
>, а все кто не согласны могут не использовать std.
Или как все нормальные люди использовать вот эти функции, которые как раз предназначены для лоу левел пердолинга.
https://doc.rust-lang.org/std/ptr/fn.write.html
https://doc.rust-lang.org/std/ptr/fn.read.html
Ну если уж лезть в unsafe, то можно и ссылки на неинициализированные данные брать, хуле.
Ты нихуя не понял о чём речь. Есть стандартный трейт для чтения данных: https://doc.rust-lang.org/std/io/trait.Read.html
И вот функция непосредственно для чтения:
> fn read(&mut self, buf: &mut [u8]) -> Result<usize>
Переменную buf без UB можно передать только предварительно инициализировав, потому что передаётся не указатель, а ссылка. И этот трейт Read является одобренным STD для блокированного чтения вообще всего.
Микрософт уже свой аналог раста (только лучше) разрабатывает: https://github.com/microsoft/verona
Без сопливых обойдутся.
Ну вот под этим предлогом могут "обосновать" покупку Мозиллы, типа "нам ваш опыт раста пригодится".
Да там и так из раста потихоньку утекают умы. Вон недавно алекс кринтон ушёл. Правда куда ушёл - неизвестно.
>шутишь про два фреймворка за год на жс
>переписываешь проект под каждый мейнстримовый язык раз в пару лет
Почему именно микрософт?
У них и так пачка мертвых технологий во всё больше загнивающей экосистеме
>Мозилла продастся Микрософту
Есть новость, где почитать? Мозилла, вообще-т, НКО, совсем продаться она не может.
Алсо, у раста уже набралась критическая масса заинтересованных компаний и без мозиллы - можно будет забацать отдельный фаундейшн с донатами.
Совсем недавно, когда новые архитектуры устройств выходили чаще, чем опенсорсеры успевали писать для них драйвера, у альтернативных осей не было шансов. Но сейчас, когда закон Мура больше не действует и время жизни архитектур увеличилось (тот же GCN вона сколько протянул) и будет дальше расти - кто знает, вдруг взлетит.
> и чем же?
Там лучше курсором было выделено. И очевидно он лучше тем, что сделали его ОНИ сами.
Когда собираешь топовый комп, а выходящая через полгода игруля указывает его спеки как минимальные - вот это действует. А то, что сейчас, это кошачьи слёзы. Даже эти изменения 14->12->7 нм далеко не те, что раньше. До 3х нм доползут, а дальше жизни вообще не будет. Ещё 3d компоновкой пугают, но сразу проблемы с охладом, сводящие на нет полученные преимущества.
Сорри за сажу.
Ну, то, что макакены нынче не думают о перформансе от слова совсем (см всякую хуйню вроде пабга или говнину из шапки, у которых графика 2012-го (ебаный кризис 3 в 2013 выглядел в 40 раз лучше) и требования как у ебаного космолёта даже по меркам 2020) — это, конечно, показатель.
Да и не факт что до 3 нм доползут хотя бы лет через 5, даже 7 нм уже трудно окупить, всё же зависит от окупаемости инвестиций в конце концов.
Опять макаки какую-то сраную магию хотят, блет.
macro_rules! kek {
($float:expr, $code:tt) => {{
if $float.is_nan() {
panic!("it' fucking NaN!")
} else {
$code($float)
}
}}
}
Блин ну попросили же не в ручную
struct Yoba { inner: f32 }
impl Yoba {
fn new(f: f32) -> Self { Self { inner: f } }
fn mut(&mut self, f: f32) {
if f.is_nan() { panic!() }
*self.inner = f;
}
Поскольку Assign операция не оверлоадится, только так можно, всё время используя .mut().
Если её запустить без аргументов, то она закономерно падает в панике, но при этом компилятор не показывает номер строки с ошибкой. Вместо этого показывает номер строки в одном из модулей растовской библиотеки(libcore/slice/mod.rs), но это не то. Как заставить компилятор показывать ошибочную строку именно в test1.rs?
Нужно установить переменную окружения RUST_BACKTRACE в 1 и компилировать с panic = "unwind" в cargo.toml (но он так делает по-умолчанию). Там на 17 месте и будет main
> 17: playground::main
> at src/main.rs:6
Ах да, если компилируешь в релизном режиме нужно установить в cargo.toml парметр debug = 1 (можно 2, но тогда код будет медленней, а 1 достаточно для бэктрейсов). Ну и на винде pdb-файлик он не копирует c exe-шником - надо ручками брать из каталога deps.
Спасибо.
Лишь с RUST_BACKTRACE=1 и panic=unwind не выводилось, а вот с debug получилось. Точнее с debuginfo
rustc -C debuginfo=1 test1.rs
Ну у меня в cargo.toml есть специальное указание для генерации информации для отладки в релизном режиме:
[profile.release]
panic = "unwind"
lto = true
debug = 1
Я её использую для логирования паники с этим крейтом: https://crates.io/crates/log-panics (там устанавливать RUST_BACKTRACE уже не нужно, потому что код записывают всю информацию в лог-файл в любом случае).
Сука, аж бесит.
Очевидно же, что хочет преобразовывать Pet<A> в Pet<B> при помощи трейта From. Но конпелятор жалуется, что преобразование из Pet<A> в Pet<A> уже определено в std и потому его имплементация трейта недействительна.
Вот именно. Я хочу преобразование для разных дженерик типов, о которых известно только то, что они именно что разные. Но известно только мне, я не могу донести это конпелятору, который жалуется, что у него уже есть определение для одинаковых типов и зачем, мол, ещё одно.
Я помню первые тесты, раст болтался где-то между джавой и с++. Не буду хейтить, может и правда допилили и все там внутри стало шустро. Но больше выглядит как подгонка под все эти недо-тесты.
1) Насколько раст хорошо подходит для прикладных приложений. Это скорее будет похоже на разработку на С++ или будет уже какой-то уровень JAVA?
2) Какие основные преимущества языка?
3) Какие фатальные недостатки?
Поясню, есть возможность выбрать язык под проект, раст выглядит таким универсальным языком с перспективами, хочется знать общую картину по языку.
1. Ближе к жабе в плане того, что есть инфраструктура либ и зависимостей и безопасная работа с памятью, а трейты похожи на интерфейсы. Даже лучше жабы в том плане, что нет сюрпризов в виде неожиданных null.
2. Сахарный, безопасный, быстрый.
3. Сложноват для начинашек, нельзя вот так просто взять и сразу начать писать большую приложуху, каждому разработчику придётся съесть свой пуд соли.
>не охота с головой в него погружаться
Тогда я бы не советовал
Всё-таки основные фишки языка слишком специфичны и требуют
отдельного осиляторства
>Это скорее будет похоже на разработку на С++ или будет уже какой-то уровень JAVA
Ближе к жабе
Лично я на расте из серьёзного написал (точнее переписал с C#) только специальный сервер, который общается с устройством через COM и передаёт данные дальше через GRPC. Разница только во времени запуска программы и потреблении памяти (с C# было около 160Мб, на расте 1.4Мб, лол).
Понимаю, что ничего не понимаю, но помогите мне рализовать такую простенькую макакофабрику. Переписываю один свой старый проект, где очень нужно что-то похожее на то, что я попытался изобразить.
Или это незаконно вообще -- делать фабрику dyn Trait?
1) Тут
> struct Factory<T: Animal + FromString + ?Sized> {
можно оставить просто
struct Factory<T: ?Sized> {
в расте в определении структуры параметры нужно уточнять только в том случае, если это необходимо. В твоём случае необходимости в Animal и FromString нет.
2) Тут
> impl<T: Animal + FromString + ?Sized> Factory<T> {
нужно убрать FromString. Он в имплементации не используется и потому может быть спокойно удалён
impl<T: Animal + ?Sized> Factory<T> {
После этих исправлений код компилируется и работает.
> Понимаю, что ничего не понимаю
И да, код не компилировался потому что у тебя две ошибки:
1) dyn может использоваться только с одним трейтом, а ты требовал, чтобы параметр T имплементировал два трейта: Animal и FromString. В теории этом можно решить определив трейт Animal так:
trait Animal: FromString {
fn say(&self) -> String;
}
тогда каждая структура имплементирующая Animal должна будет имплементировать и FromString. но тут возникает вторая проблема:
2)
trait FromString {
fn from_string(s: String) -> Self;
}
> fn from_string(s: String) -> Self;
Такая функция (где нет параметра self) не может использоваться в dyn-трейтах. Можно "исправить" заставив функцию быть невидимой в них:
trait FromString {
fn from_string(s: String) -> Self where Self: Sized;
}
тогда Animal может быть зависим от FromString и быть использован в dyn-трейтах. Но такой код уже начинает попахивать. Да и самой фабрике FromString как бы не нужен.
Впрочем ей и Animal не нужен (тогда зачем вообще там параметр T?). Почему бы просто не сделать
> impl<T: ?Sized> Factory<T> {
?
> Понимаю, что ничего не понимаю
И да, код не компилировался потому что у тебя две ошибки:
1) dyn может использоваться только с одним трейтом, а ты требовал, чтобы параметр T имплементировал два трейта: Animal и FromString. В теории этом можно решить определив трейт Animal так:
trait Animal: FromString {
fn say(&self) -> String;
}
тогда каждая структура имплементирующая Animal должна будет имплементировать и FromString. но тут возникает вторая проблема:
2)
trait FromString {
fn from_string(s: String) -> Self;
}
> fn from_string(s: String) -> Self;
Такая функция (где нет параметра self) не может использоваться в dyn-трейтах. Можно "исправить" заставив функцию быть невидимой в них:
trait FromString {
fn from_string(s: String) -> Self where Self: Sized;
}
тогда Animal может быть зависим от FromString и быть использован в dyn-трейтах. Но такой код уже начинает попахивать. Да и самой фабрике FromString как бы не нужен.
Впрочем ей и Animal не нужен (тогда зачем вообще там параметр T?). Почему бы просто не сделать
> impl<T: ?Sized> Factory<T> {
?
Анон, спасибо большое, что нашел время на разбор моей дрисни! Я, в общем, хотел просто описать контракты, чтобы во время компиляции все упало, если структура не реализует FromString (в реальности там будет json::Value, и из него будут браться данные для инициализации структуры) и не реализует Animal. Но я вообще не в том месте решил городить ограничения, фабрике вообще должно поебать, как оно там все будет реализовано. Великолепно меня Раст пнул за непонимание того, что я хочу на самом деле сделать.
Написал чуть более обобщенно. Не очень понимаю, как все же далее ограничить в фабрике регистрацию только тех dyn Trait, для которых будет реализован FromString. Этот трейт важен, так как, как я уже выше говорил, на самом деле там из JSON данные разгребаться будут, это такой конструктор, и без подобной фабрики мне не решить задачу.
>>28467
Спасибо и тебе, дружище! Сейчас экспериментировал и самостоятельно дошел до всего, что ты расписал, и примерно начал ситуацию понимать. Есть надежда, что я не совсем идиот.
> trait Animal: FromString {
Я тоже подумал, что это что-то не совсем адекватное, хоть и полностью решает вопрос с жестким контрактом на этапе компиляции.
Поэтому буду искать другое решение, но пока не сильно понимаю, в какую сторону идти. Насколько понимаю, я не могу от dyn Trait требовать реализации какого-нибудь интерфейса трейта.
Ты хочешь динамику, которая тебе всё обработает в рантайме. Но дело в том, что все эти
trait Yoba и fn foo(a: YobaType) -> Yobatype
работают только на этапе конпеляции. Чтобы разграничить структуры в рантайме, надо навешивать им флаги. Если у тебя там всё просто, то эти флаги элементарно енумом можно сделать:
enum Flagged<D: Data> {
Foo(D),
Bar(D),
}
fn try_pet(d: Flagged) -> Option<> {
match d {
Foo(data) => pet(data.into_animal()),
Bar(data) => None, // It's bot animal!
}
}
У меня порт с ECMAScript-языка (AS 3.0).
> Если у тебя там всё просто
Смотря что имеешь в виду. Структур там ну сотни, наверное. Попытаюсь объяснить, с чем вообще имею дело.
Есть JSON-сопля примерно такого содержания: https://pastebin.com/WMc001Sh
В `actions` описана декларативно игровая логика, и у нас тут в каждом действии могут быть десятки разновидностей Requirement, Amount (вместо числа 30 мог быть сложный объект для расчета скидки при покупке) и прочее такое. Прикладываю примерные иллюстрации того, как все выглядело в оригинале.
В рамках изучения Rust пытаюсь реализовать что-то похожее, но пока хуйню делаю какую-то.
Кто-нибудь на ozon'е с таким еще сталкивался? Что это, просто они что-то перепутали, либо ж иногда годнота все же у них продается без запредельной наценки?
>Потому что если компилятор ничего не знает о A/B, то A = B = T
ну, вот ты, умный, расскажи, как донести до конпелятора, что я имплементирую для A != B, чтобы он шёл лесом со своей имплементацией для A = B
Каким образом компилятор по твоему должен отличить тип A от типа B, если о них ничего неизвестно?
>если о них ничего неизвестно?
Как же неизвестно, когда известно, что А точно не В. Я даже готов сообщить об этом конпелятору. Куда писать, в какое окошко?
Суть: у нас есть собаки, физически одинаковые (на уровне структуры), но есть дикие и домашние. Дикие имплементируют кусание, домашние - нет. Вот хочу я превращать диких в домашних со скоростью света - так как различий в структуре нет, мне нужно только копировать данные, ничего не меняя.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=12cf296b2e20689c94aa73920c5a10cc
проблема в том, что речь не о собаках и не о всего лишь 2х типах, там их несколько больше. Я, конечно, могу заимплементить для каждого случая, но бля, зачем, почему, какого хуя - если все они одинаковые?
#![feature(specialization)]
Разве нет?
Ну или
struct Foo<A>(A);
impl<A> Deref for Foo<A> {
type Target = A;
...
}
impl<A> DerefMut for Foo<A> {
...
}
impl<A> Trait_1 for Foo<A> {
fn yoba(self) { (self).yoba() }
}
struct Bar<B>(B);
impl Deref for Bar ... { ... }
impl DerefMut for Bar ... { ... }
impl<B> Trait_2 for Bar<B> {
fn other_yoba(self) { (self).other_yoba() }
}
Блин, забыл, что двач звёздочки жрёт. Короче, делаешь тип-обёртку под каждый трейт, имплементишь дерефы для обёртки и имплементишь сам трейт для обёртки через дереф. Там, конечно, надо написать
<A:Trait_1>
в паре мест, но вообще всё просто. Задерефить не забудь, там вроде видно, в каком месте звёздочки стоят.
Т.к. ты не показываешь как ты хочешь это использовать, то вот, держи: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6f62e5c8fcb846343ad393ed44936ae2
Просто хуёришь обёртку с <T> генериком. Потом под этот генерик подставляешь любую нужную структуру, которая может в impl Trait, потом через Deref имплементишь Trait для обёртки, и вуаля, ты можешь использовать трейт как структуру.
Ты дурак? Он хочет донести trait solver'у, что хочет имплементировать From для всех T и U кроме T = U. Deref работает уровнем ниже. И сейчас это сделать попросту невозможно и даже в планах нет разрешать при проверке трейтов что-то кроме X = Y.
Я думаю, что надо понять, что он хочет на самом деле. Потому что вероятно, есть более подходящие варианты достичь результата.
В твоём примере есть Dog, который может конвертироваться в Pet(Dog) и Wild(Dog). А вот чтобы Pet(Dog) <-> Wild(Dog) - такое можно? А Pet(Poodle(Dog)) <-> Wild(Dog) ? Как я понимаю, нужно конвертить Any(Dog) -> Dog, но что-то не вдуплю с разбегу, как это.спать пора, видать
Нужно именно это, так как эти сущности должны сперва кусаться каждый по-своему, а уж потом превращаться одно в другое.
Кажется ты пытаешься изобрести ооп в стиле с++. Может не надо?
Это блядские генерики. Просто делаешь
impl<A> Foo<A> {
fn get(self) -> A {
self.0
}
и пишешь
let foo = Foo(...);
let bar = Bar(foo.get());
Если ты хочешь контролировать фичи вкладывая типы в друг в друга, наверное как-то так: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b5a5337a290a8998914bdb1db8acfc2f
@
ПОЛОВИНА ЛИБ - "ЭТО АЛЬФОВЕРСИЯ, НЕ ТРОЖЬТЕ!"
@
ДРУГАЯ ПОЛОВИНА - БИНДИНГИ К ЦЭПЭПЭ
Пишите своё>
Как тебе не стыдно. Ты забыл про самое важное:
БЕЗОПАСНАЯ БИБЛИОТЕКА НА БЕЗОПАСНОМ ЯЗЫКЕ
@
2145 UNSAFE-БЛОКОВ
1) Небогатый пул либ, в проде этот яп соснет хуйца в виду отсутствия большого количества либ для решения самых разных проблем, а писать либы с нуля - прерогатива далеко не всех прогеров. Хуяк-хуяк и продакшн не получится, а бизнес этого требует.
2) Есть кресты и си с огромной базой, огромным кол-вом специалистов. Раст как бы пытается быть безопасной версией оных, но это отличие недостаточно для того, чтобы все поголовно перешли с крестов и си на раст.
3) Эзотерический синтаксис, не самый простой язык в общем (хоть кресты все равно сложнее, офк). В виду того, что это системный яп, он требует имплементации низкоуровневого дрочева по типу зацикленных связынх списков, которые нельзя заимплементить без ансейфа, который нивелирует всю мякотку безопасности раста. В итоге получается, что серьезный системный софт, написанный на расте, требует использования ансейфа во многих моментах, что убивает весь смысл раста как замену си и крестам. А шило на мыло никто менять не хочет, раст без безопасности - ненужная хуета, так как есть кресты и си с огромной инфраструктурой и тонной спецов. Да и весь легаси тоже надо как-то поддерживать.
>раст без безопасности - ненужная хуета
Ну это же вроде как редкие случае, узкие подконтрольные места? Есть ли смысл все в абсолют возводить?
Проведу аналогию с null и тем как сейчас стали бороться с этим в управляемых языках (котлин, шарп, тайпскрипт...). В общем, смысл в том что вся эта борьба минимизирует проблемы с null, но полностью не решает. Так же остается класс задач, где null нужен.
Почему и тут раст должен прям полностью быть safe (или прям это у них фанатичная позиция на этом)?
Юношеский максимализм, сэр.
>>29118
БИБЛИОТЕКА ДЛЯ ТРУ-ФП ЯЗЫКА
@
БИНДИНГИ К СИШНЫМ ЛИБАМ
Вас никто не ограничивает в выборе путей для профессионального развития. Вы же не сотрете свои высеры в старых тредах, если вдруг Раст или Хаскель победят в мире разработки ПО лет через двадцать. Зачем срать тогда? Берите из разных технологий, языков, фреймворков и паттернов лучшее, срывайте лучшие из плодов человеческой мысли.
ансейф ансейфу рознь. Одно дело, когда ты делаешь что-то вроде transmute и в том, что внутри валидные данные, ты мамой клянёшься.
А другое, когда ты наябываешь борроучекер, со словами "ну не, тот поток точно записать ничего не успеет" - а потом оно успевает в продакшене.
>>29562
>класс задач, где null нужен
В той же жабе есть и Optional, и null. Почему они не могут во всех вызовах, где может быть возвращён null, обернуть результат в Optional? Дык, не нужен им null, а просто легаси же. Вот пусть и ебутся с null, пока не закопают вместе с языком. В расте этого изначально нет, и слава б-гу. Хотя со временем свой груз легаси-"фич" наверняка образуется.
>Хотя со временем свой груз легаси-"фич" наверняка образуется.
Порядок дропа. Уже превратили в стейбл фичу из-за легаси.
> А другое, когда ты наябываешь борроучекер
Ну ты в абсолютно любом языке можешь выстрелить себе в ногу, тут уже только от тебя зависит. Вообще за такие ансейфы в приличном обществе пиздят, и возможно даже ногами. Для защиты от подобного как раз и есть код-ревью или опенсорс.
Все таки без ансейфа язык был бы совершенно бесполезным (ты бы даже в консоль нихуя не напечатал, да).
>>29607
Поясни плиз
struct Yoba {
a: Foo,
b: Bar,
}
let y = Yoba::new();
drop(y);
Порядок дропа чётко определён в расте. Вроде бы сперва падает b, потом a, но это неточно, потому что я давно об этом читал. Но порядок точно определён.
Ну, скажем, ты повешал на дроп коллбэк и тебе кровь из носа важна очерёдность исполнения этих коллбэков.
Раст уже обогнал по количеству библиотек перспективные языки типа Nim и D, которые появились раньше.
>D
С D вообще смешная история была: на нём изначально был написана первая версия OpenMW, но потом коммьюнити решило, что ну его нах, и переписали на крестах. С растом пока чаще случается наоборот - на нём переписывают с крестов.
Там оправдывали тем, что на расте мало программистов, которые будут поддерживать продукт. Их можно понять.
Короче выглядит пока как то, что нужно знатно упороться, чтобы сделать такое. Но при этом я совершенно за, чтобы поведение было четко определено все таки.
Вот из-за таких как ты легаси выглядит как говно, а не как конфетка.
Они там субд и модули для машинного обучения разрабатывают, так что до веб макакинга еще далеко.
Мьютексы.
Для миграции на rust было бы удобно, заодно и библиотек прибавилось бы.
Потому что Go -- язык с GC, и напрямую код под концепции владения не переделать? Потому что все interface{} станут unsafe {}? Потому что на хуй не нужно низкосортный (как минимум с точки зрения языка с поддержкой обобщений) код переносить куда бы то ни было вообще, ведь архитектурных и композиционных различий там будет миллиард?
Если элементы Copy, то уже сейчас можно использовать https://doc.rust-lang.org/std/primitive.slice.html#method.copy_from_slice
В теории можно правую часть забирать и элементы перемещать (а все объекты в расте можно перемещать), но без ручного ансейфа это не сделать, а в виде функции не добавить, потому что unsized rvalues не стабильны (а они нужны чтобы функция могла принимать непосредственно слайс, а не ссылку на него).
С вектором всё понятно, он гибкий. А я хочу именно массив, для, типа, скорости.
Суть
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10ab13f92246ec0d69de4c6343692e48
the size for values of type `[usize]` cannot be known at compilation time
но конпелятор явно пиздит, так как цикл я задаю той же константой, что и размер массива. Т.е., там всё просчитывается, другое дело, что разрабы конпелятора до этого надеюсь, пока не добрались.
Прост матчи со слайсами приделали - вот я и подумал, что тут как-бы похожая задача, даже попроще.
>>34502
Бля, со слайсам заработало
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5448442ce184030741a1682ca2d121ab
>>34505
Не, ну почему нельзя напрямую заебошить через "=", чтобы как в лучших домах?
> Бля, со слайсам заработало
Потому что массив автоматом может превращаться в слайс.
> Arrays coerce to slices ([T]), so a slice method may be called on an array. Indeed, this provides most of the API for working with arrays.
> Ты померил, надеюсь не от жопы?
Ну как минимум массив (если не использовать Box) выделяется на стеке, а вектор всегда в куче. Так что если элементов мало и их количество известно, то использовать вектор нет смысла. Другой вопрос, что без константных генериков использовать массивы с более чем 32 элементами очень сложно, потому что для них отсутствуют куча трейтов.
> Не, ну почему нельзя напрямую заебошить через "=", чтобы как в лучших домах?
1) Наверняка это значительно усложнит парсер. Сейчас в расте даже избавляться от ебанутого синтаксиса вызова генерик функций (yoba::<u32>()) не хотят (конкретно, избавится от этих :: перед списком типов).
2) Слишком много магии, а этого расторазрабы очень не любят. Вместо того чтобы вводить новый синтаксис, можно это решить функцией
fn move_from_slice(&mut self, src: [T])
но чтобы эта функция заработала нужны unsized rvalues. Пока что можешь использовать unsafe-аналог: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e5e2c0dcb4120f3d6f187c30132deb6a
> Пока что можешь использовать unsafe-аналог
Ну и можно вынести в макрос для реюза: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cb4b20f60bdc6c4d82c0538abc2ddf63
Единственный недостаток: будут странные ошибки или потенциальные ub если скормить макросу не слайсы.
Хотя ManuallyDrop тут лучше подходит: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1d0f7e04db2955d310d41570a5707772
Там не в слайсах дело, а в том, что элементы слайсов должны иметь трейт Copy (то есть должны быть тривиально копируемы).
> что размеры только в рантайме чекаются
Тут да. Чтобы чекать в компил-тайме нужны константные генерики, которых до сих пор нет.
> clone_from_slice
copy_from_slice будет быстрее (он тупо копирует кусок памяти, а clone копирует по-элементноб вызывая у каждого функцию clone).
Потому что в рантайме никаких проверок нет. Все процедуры влияющие на безопасность (borrow checker например) происходят только при компиляции. Дальше код такой же как и на C. Ещё есть что-то связанное с нулевой стоимостью абсстракций таких как обобщённые типы. Где просто под каждый возможный тип при запуске программы резервируется функция реализующая этот тип. Это очень быстро работает в рантайме.
Он не такой же быстрый. Кидаешь в godbolt две идентичные проги на C и раст и смотришь на сгенерированный ассембли. Там случае с алиасингом разве что оптимизируются llvm лучше
А зачем вообще нужны динамические сборщики мусора, как в Java и C#, если можно делать как в Расте, собирая мусор при компиляции?
Чтобы программисты не рыдали, пытаясь писать графовые структуры. И да, раст никакой мусор при компиляции не собирает, он просто контроллирует времена жизни
Каким образом? В расте же не нужно вручную освобождать память, за тебя это делает компилятор.
Компилятор это не бесплатно делает, а ограничивает действия которые может сделать программист, а это как раз таки и усложняет разработку. конечно смотря разработку чего
>А зачем вообще нужны динамические сборщики мусора, как в Java и C#, если можно делать как в Расте, собирая мусор при компиляции?
Отличный вопрос! Для того чтобы знать ответ, нужно раскопать несколько вещей.
borrowck это не сборщик мусора, это механизм, который позволяет проверять на этапе компиляции что ссылки не "живут" дольше того на что они ссылаются. Освобождение ресурсов происходит автоматически по концу скоупа в котором живет переменная (есть исключения вида move semantics и std::mem::forget).
borrowck не решает все возможные задачи по организации ресурсов, и не подходит для всех задач. Если ты попытаешься написать двусвязный список на расте, то столкнешься с огромным количеством веселья. https://rust-unofficial.github.io/too-many-lists/ . Почему так? Потому что в с двусвязном списке крайне сложно гарантировать что все указатели нормальные И время жизни известно на этапе компиляции. Приходится использовать более сложные структуры данных, такие как Rc, rc::Weak, арена+индексы.
Так же, довольно сложно эффективно выразить в рамках borrowck такие структуру данных как граф и деревья со ссылками к родителям. И такие структуры данных очень часто используются во всяких UI. Есть разные решения, но они все идут в обход borrowck -- чаще всего используются или сырые указатели (что unsafe), Rc/Arc или арена+индексы. Сборщики мусора же идеально подходят для задачи "я хочу иметь ссылки во все стороны и не заботиться о памяти".
Еще хочу добавить что в расте технически возможно использовать сборщик мусора в виде библиотеки, таким образом можно совместить сборку мусора для структур которые этого требуют и borrowck для структур которые этого не требуют. Большинство программ этого не делают и в этом не нуждаются.
> Если ты попытаешься написать двусвязный список на расте, то столкнешься с огромным количеством веселья.
Это было до появления Pin. Сейчас можно даже написать безопасный intrusive двусвязный список, который вообще не будет выделять память, а вся информация для списка (ссылка на следующий и предыдущий элементы) будет храниться непосредственно внутри элементах списка (потому что Pin будет гарантировать, что ссылки не сдохнут и элементы никуда не переместятся). Мегакрутая вещь, потому что позволяет обойтись без аллоцирования памяти внутри асинхронных алгоритмов (поскольку можно делать списки, хранящие внутри себя Future без выделения памяти).
Я мимокрокодил, но можно поподробнее? Я из пинов трогал только Box::pin и вообще без понятия, как там список будет выглядеть
Pin в отличии от простых ссылок помимо гарантии о том что объект не умрёт, даёт и гарантию, что объект не будет перемещён. Но, однако, ссылки всё так же остаются ссылками, а значит тебе придётся ебаться с лайфтаймами, если хочешь писать чисто безопасный код. А учитывая, что зачастую возможностей раста не хватает для адекватной работы со структурами с лайфтаймами (например из-за отсутствия GAT), то многие предпочитают по старинке использовать unsafe.
>>39956
Он настраивается если тебе что-то не нравится: https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
Я лично использую дефолтный пресет.
@rustlang_ru
Ещё есть вакансия на руби, где в требованиях (или пожеланиях, не помню) указан опыт программирования на расте.
Не, прост вакуха интересная.
Кто-нибудь апплаился уже нан неё?
Я дотнето-питоно-энтерпразо-блядь, мне не по чину, а тут такие-то требования и задачи, аж ухх.
m := scores["Yellow"]
В расте:
let m = scores[&"Yellow".to_string()];
А то вот это уже не работает https://stackoverflow.com/questions/25877285/how-to-disable-unused-code-warnings-in-rust
Что то ты или тупой, или пиздишь https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=176f7470b3b04e60f72b6cd4241bb7b2
Ну ты ведь только доказал, что сделал хуйню, и естественно компилятор не может за тебя понять, как ее интерпретировать. У тебя там в ключе хуйня в виде &String (хорошо, если один уровень ссылок). Так что ССЗБ, да.
.iter создает интератор по &'life0 &'static str, вместо &'static str. так, что, тебе нужен into_iter который превратит массив в полноценный итератор
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3648212cada0270fbc4e10f0ea06b157
Пошел нахуй.
Почему if со сравнением ссылок срабатывает? Всегда автоматически разыменовывает что ли? Какие ещё операторы так делают? Где про это подробнее почитать в официальной документации?
Это не в конструкциях дело, а в том, что Rust автоматом дереференсит объекты для вызова методов. Для сравнения у нас есть трейт std::cmp::Ord, и для сравнения a и b вызывается Ord::cmp(a, b). Тут-то и происходит дереференс.
В Rust Reference расписано подробнее: https://doc.rust-lang.org/reference/expressions/method-call-expr.html
Если очень хочется сравнить ссылки, обратись к ptr:eq.
Спасибо. Странно, что для такого строгого языка как rust сделали при сравнениях неявный автодереференс. То ли дело https://play.golang.org/p/TSjp4-HumQc
Ты представляешь, как будешь вызывать функции для Arc<Mutex<Box<T>>>? (T).do_something().
> для такого строгого языка как rust
Строгость — она вообще не об этом. Тут все строго, но в безопасных моментах может быть неявно. Если неявно и однозначно не получается, копилятор ругается. В автодереференсе подводных нет.
> То ли дело
В Go нет перегрузки операторов и сравнения не реализованы для ссылочных типов. Сравнения там вообще только для примитивов есть, поэтому никаких сюрпризов, это часть их подхода ко всему.
В то же время, посмотри на пример пикрелейтед. Методы для структуры вызываются независимо от того, как они объявлены (rect там просто является индикатором сайд-эффектов при вызове метода) и независимо от того, по структуре r ты его вызываешь или по ссылке на нее rp. Тут тоже автодереференс работает во всю, ты просто ищешь его в том единственном месте, где в Go его нет по принципиальным причинам.
Забыл, что звездочки съедает парсер.
> (T).do_something()
(✱✱✱T).do_something().
> (rect там просто является индикатором сайд-эффектов при вызове метода)
✱rect
Что-то я не пойму, а что если один из потоков уже вовсю юзает к нему доступ - что будет со вторым? Никакого Result или Option там нет, возвращается сразу указатель. Или оно само ждёт?
>а не сам указатель.
Имееется в виду данные на которые указатель указывает.
Пример реализации стека
http://aturon.github.io/tech/2015/08/27/epoch/
Нет, смотри:
AtomicPtr - это просто кучка байтов, которые могут использоваться как адрес.
И когда ты изменяешь эту конкретную кучку байтов, зовущуюся AtomicPtr, она изменяется атомарно. Данные по этому указателю обычные и изменяются обычно, а не атомарно (кроме случаев, когда твой указатель указывает на другой атомик, но это другая история).
>>48573
Никто ничего не ждёт. Хочешь атомарный доступ к данным по указателю - юзай Mutex или RwLock (или ^const AtomicUsize, если указатель нужен, а не ссылка, как &AtomicUsize, если тебе надо хранить маленькую цифру, а не большой слайс).
а што случилось с православной версией расбука?
она еще жива или всё?
Ну, смари:
1. У тебя прописан лайфтайм для функции, то ты и возвращаешь с энтим лайфтаймом. Но это может быть немного муторно.
2. Ты передал в функцию вектор и возвращаешь указатель на элемент этого вектора. Годится не для каждого случая.
3. Возвращаешь с &'static - но это немного некошерно, как я понимаю, так можно сделать утечку. (более опытные аноны пусть поправят)
4. Самое лучшее - стараться писать так, чтобы функция возвращала прям-таки сам объект. То есть, создавала какие-то новые данные и их возвращала. Тогда никаких вопросов к ней не будет.
Если дереференсить по полученной ссылке, то может и будет. А если ты создал объект, то никакого перемещения в памяти не будет.
Да не, в расте стандартную либу ещё читать можно. Про всё говорить не могу, но некоторые вещи точно.
В расте как раз никакого ада и никаких препроцессоров, только макросы иногда странные, но в стдлибе все макросы простые если не по коду, то хотя бы по логике. А ещё там везде охуенная документация.
Зайди в МВП тред, там ссылка на гитхаб со всякой сранью по крестам. Но тебе кресты не нужны, только часть про то, как работают процессоры и RAM. Видосов там вроде на час-два всего. После этого уже становится понятно, что такое указатели, биты и прочая срань.
>Как там раст поживает?
Хорошо
>сделать упор на С++?
>Возможно ли найти работу?
Ты же никогда не работавший студент?
Когда что-нибудь решат с целым сонмом проблем. Например, линуксы не могут писать на расте, потому что нет хотя бы полустабильного ABI, а новые версии раста выходят чаще, чем новые версии линупса.
Есть и другое. Раст хорош, но пока что с легаси слезать никто не хочет, потому что раст сложный и учить его дорого.
> дедушек типа Си и крестов
Им нахуй ваши безопасные языки не нужны. Няшные UB и use-after-free - самое лучшее что случалось в IT.
А не наоборот? Кресты - те же Си по производительности, но с мегакрутым STL, где есть дохуя структур данных и нулевых по стоимости абстракций, ООП и умные указатели, позвляющие минимизировать шансы иметь уязвимости типа use-after-free, nullptr dereference, double free.
Я считаю, что Сишка уступит расту лет через 10, но кресты несвергаемы в ближайшие лет 50 так точно
Кому им? Безопасники потеряют хлеб, по крайней мере в лоу-лвл бинарщине, да, но компаниям только в плюс, их хотя бы по одному вектору перестанут ебать.
У STL самая большая проблема - это переусложнённость. И одна из причин - эксепшоны (которые, что смешное, любой кого волнует перформанс полностью отключают), которые нужно учитывать. Отсюда некоторые коллекции медленней чем могли бы быть.
От Линуса зависит разве что будущее Линукса, но никак не будущее всего мира программирования. То, что Линукс на раст перепишут только через труп Торвальдса - это и ежу понятно. Но я говорю глобально о мире. В итоге через 10 лет максимум что останется - это суперсложные дыры в пространстве ядра, юзерспейс должен семимильными шагами перестать юзать дырявые япы. Какой от них смысл, если раст быстрый как си и плюсы, но безопасен и его код нельзя взломать по вектору ошибок с памятью?
ты давно видел чтобы на чистом цэ писали? а вот где то заткнуть им дырку он минималистично идеален, кресты сложные и неговнокодить на них тяжело, надо дохуя знать чтоб ненаделать пиздеца, я например понимаю что я их не настолько знаю чтоб увидеть эти подводные камни.
> ты давно видел чтобы на чистом цэ писали?
Ололо, прошивки для любой эмбедщины, драйвера (Линукс, здарова), рилтайм, средства виртуализации типа гипервизоров. Там почти 100%ый Си код
> ну а кроме не так уж часто
Братан, это ОГРОМНЫЙ кусок рынка, который с развитием интернета вещей только растет в геометрической прогрессии, алло. К тому же, драйвера все же пишут чаще на чистом Си, и на винду, и на Линукс.
> ха
Какой смысл подвергать себя риску, особенно если это софт, который крутится на сервере и открыт ВСЕМУ МАТЬ ЕГО ИНТЕРНЕТУ, если можно без потерь юзать яп, у которого неуязвимая память? Где логика блять?
Для начала не мешало бы аллокаторы доделать. Да и константные генерики тоже (без них работать с массивами - боль). Обе фичи в зачаточном состоянии и вряд ли до следующего года будут доделаны.
Раст, может быть и такой же быстрый, как плюсы, но точно не как С. Вернее сказать, идиоматичный код на Расте и плюсах всегда будет медленнее сишного, потому что не бывает на самом деле никаких зерокостабсракшнс: просто в плюсах и Расте обычно делают выбор в сторону понятности/выразительности без (как правило) существенной потери производительности. И это хорошо, потому что писать на сях - удовольствие разве что для гурманов (читай: ебанутых) типа Торвальдса.
В отличии от C++ в расте "зиро кост" имеет именно смысл "такой же быстрый, как и оптимизированная версия написанная вручную" (а не "нет оверхеда если фича не используется"). Те же асинхронные функции в расте например в ночнушке уже могут полностью оптимизироваться, как будто асинхронщины нет вообще: https://rust.godbolt.org/z/jL_5sC
Эти зирокост фантазии соответствуют реальности чуть чаще, чем никогда. Речь даже про более простые вещи, чем асинхронность.
В с++ тоже (так-то этот маркетинговый прикол Страуструп сочинил)
Ты хоть один баг-репорт заполнил где конкретная абстракция выполнялась медленней чем код без неё? Или речь про твои собственные фантазии?
Именно. Потому что они воспринимаются как баги и как отсутствие нужных оптимизаций, а не как фичи. Например раст до сих пор не умеет в NRVO (которому С++ научился лет двенадцать назад) из-за чего куча кода с Box работает медленней чем могла бы (особенно если LLVM не сообразит соптимизировать).
>Ты же никогда не работавший студент?
Практически, да. Делал сайты и прочую херню.
Но в последнее время подсел на плюса и раст. Вот и думаю профессионально заняться, всяко лучше чем в css анимации пилить.
Я замудохался ошибки к единому типу приводить, сука, а тут такое.
Суть - нужен асинхронный метод для трейта, ебать его в рот.
он решил уберечь мир от своего архитектурного гения
> нужен асинхронный метод для трейта
Раст такого изкаробки пока не поддерживает (и в ближайшее время не будет). Тут только костыль использовать: https://crates.io/crates/async-trait
прочитай в оригинале она не сложная
Ладно, буду плюса задрить
Чего можно создать/допилить полезного на расте?
>>58169
Дохуя всего.
1. Не все нужные либы написаны, не для всего есть биндинги.
2. В том, что написано, куча недостающего функционала. Тот же Image не умеет 16-бит png схоронять.
3. Очень многое из написанного заброшено и устарело. Я вот открыл тут для себя swagger, OpenApi и это вот всё. Для 2.0 биндинги генератора основаны на старой версии tokio и hyper (да и сами биндинги неполные), для 3.0 вообще ни хуя нет - сам пишу может здесь покажу, как доделаю. Или попрошу помощи, если не осилю
Ну раз сказали, что всё. Опровергать бесполезно.
мака нет
> GUI на раст
> Orbtk
> 5000 р
Что-то мало. Не знаю насколько простое это приложение, но писать гуй (даже на нормальных библиотеках/фреймворках) это почти всегда боль, даже если уже есть готовый бэкенд со всей бизнес-логикой. Особенно когда начинается ёбля с интернационализацией и (не дай бог) ацессибилити.
Если ебашить хкод+свифт, то довольно просто всё будет. Очень непонятно нахуя тут раст.
Там не просто раст, но и гуй для redoxos (ОС на расте), который находится в зачаточном состоянии.
>Очень непонятно нахуя тут лучший язык современности.
ТЕМ ВРЕМЕНЕМ ЗАКАЗОВ Разработать простое GUI приложение на Rust под MacOS (Orbtk) 1 ШТУКА
Разработать простое GUI приложение на Govno под MacOS (Orbtk) 0 ШТУК
Не будет. Они от говна даже в своей фуксии откказались, потому что говно оказалось БЕЗ ЗАДАЧ. А для гуя у них флютер с дартом есть.
>флютер с дартом есть.
они этот флюгегехаймен пишут со скоростью что учебники выходить не успевают, неужели на столько говно что перепиливают постоянно
Не знаю что они там пишут, но для десктопа и даже веба эта хуита никак релизнуться не может.
Дарт давно готов, ещё раньше го вылез вроде, но не уверен. Флаттером на телефонах они гуй рисуют, так что его всегда надо будет допиливать.
Решил я, в связи с известными событиями, немного торгануть на бирже. Ну и автоматизировать немного, ессно на расте. Взялся я за неё и что вы думаете? У тинькова апишка для версии 3.0, а в swagger-gen модуль для раста только для версии 2.0.
Ну я, короче, промудохался пару дней и выкатил (вроде) рабочую версию для 3.0, отдельным модулем. Интересно кому такое?
Го я не знаю, от жабы тошнит, питон слишком распиздяйский язык для финансовых утех есть опыт.
я патологический неудачник для игор в этом казино, но идея интересная
И что прямо реально вот эту вебную парашу можно легко на расте делать?
inb4 поставил везде Clone, Copy и делаешь
А там ничего вебного, апишечка же и всё. Шлёшь запрос, получаешь ответ, десериализуешь - дальше работаешь со своей структурой. Если надо что-то заслать - сериализуешь структуру и также пакуешь в запрос.
OpenApi охуенная штука, позволяет просто набросать описание апишечки и по нему генерить клиент и сервер (в серверную часть я не вдавался).
name = "reqwest"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"hyper-tls",
"js-sys",
"lazy_static",
"log",
"mime",
"mime_guess",
"native-tls",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_urlencoded",
"time",
"tokio",
"tokio-tls",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
name = "reqwest"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"hyper-tls",
"js-sys",
"lazy_static",
"log",
"mime",
"mime_guess",
"native-tls",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_urlencoded",
"time",
"tokio",
"tokio-tls",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
Делается за пару минут при поможи жопаскрипта или петухона, зачем тебе из раста по мухам стрелять?
На чём делал hyper/serde?
>>58835
>Мне нужно всего лишь получить содержимое определённого URL
Либа должна
>уметь парсить http
>при connect уметь в tls
>быть ассинхронной
Я ничего не забыл? Поэтому у тебя любой reqwest будет такой "распухший".
>>58887
Разработчики hyper рекомендуют использовать reqwest, если тебе у тебя простой план использования.
мне вот интересно с какого перепугу его пихают везде там сам дизайн языка неоч
Один язык, один рантайм, один успех.
Я, кстати, с пятнадцатого года на Go и Python писал, и сейчас, изучая Rust рывками в свободное время, понял, что на Rust мне почти заново надо учиться писать, как если бы я на Хаскель перепрыгнуть решил. Если тебе не тяжело, поясни конкретно, в чем я неосилятор.
>hyper/serde
Я за основу взял версию от 2.0, так она и была на этом самом. Подтянул там hyper к последней версии (из-за чего пытался в асинхронные трейты, забил и сделал block_on), заимплементил енумы (костыльно, пулл-риквесты вэлкам), добавил сер-десереилизацию для времени.
Юзать как-то так:
https://github.com/swagger-api/swagger-codegen/tree/3.0.0/
>mvn clean package
https://github.com/inferrna/rust-swagger-codegen_v3
>mvn clean package
потом
>java -cp rust-swagger-codegen_v3/target/rust-swagger-codegen-1.0.0.jar:swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar io.swagger.codegen.v3.cli.SwaggerCodegen generate -l rust -i your_swagger.yaml -o your_client
Всё, крейт в your_client почти готов, нужно только руцками прописать версию и название. Я проверял на Тинькове - работает, пок что, правда, единственный запрос проверял. Одна тонкость - для поддержки ssl пока нужно немного попотеть - пикрил (потом можно перенести в саму либу, нужно только задетектить схему).
Работы там дохрена, официальная версия для 2.0 оказалась ещё хуже моей.
И при чем тут это? Ты явно неправильно меня понял.
Ага.
Зачем это говно вообще городить?
> Зачем это говно вообще городить?
По большей части чтоб не писать return Ok(govno); (или Ok(govno) в конце) для выхода из функции, а просто return govno;/govno как будто функция возвращает не Result<Govno, _> а просто Govno.
Удобна же (на самом деле было бы неплохо, особенно в функциях возвращающих Result<(), _>, где с ok-wrapping можно ничего не возвращать вообще). Ты ещё не видел свидетелей отсутствия точки с запятой у которых точка с запятой в конце выражений сразу делает язык неюзабельным говном.
>Ты ещё не видел свидетелей отсутствия точки с запятой у которых точка с запятой в конце выражений сразу делает язык неюзабельным говном.
ну я сам люблю в кожуре поковырятся, но к точкам отношусь нейтрально
>Удобна же (на самом деле было бы неплохо, особенно в функциях возвращающих Result<(), _>, где с ok-wrapping можно ничего не возвращать вообще).
руст и так местами переусложнен, а если начать добавлять исключения в одних функциях так в других не так, будет пиздец.
> руст и так местами переусложнен, а если начать добавлять исключения в одних функциях так в других не так, будет пиздец.
Так это уже сейчас можно сделать макросами (более того ты можешь писать зашифрованный код и расшифровывать его во время компиляции при помощи макросов - https://github.com/matklad/proc-caesar - пикрил). И пока что делать подобные функции даже в планах нету. Только специальные try-блоки, плюс трейт Try, чтобы можно было использовать ok-wrapping (да и оператор ?) с любым типом, а не только Option и Result, которые сейчас немношк попахивают магией.
> резалт то магией не пахнет
Я про оператор ?, который работает только с Result и Option. После стабилизации трейта Try он будет работать с любым типом, который имплементирует этот трейт и "магия" внитри Result и Option будет заменена на имплементацию этого трейта (хотя скорее всего ? уже работает через этот трейт и просто в стабильном расте ты не cможешь сделать свой тип, чтоб он имплементировал его).
Скорее мертворожденный. Он служит якобы будущей заменой Си и крестов, но на деле временный выпердыш, так как он решает какую-то микропроблему топовых системных япов (Сей и крестов), и то частично, а не полностью. Засим, недостаточно причин для тотального перехода на Раст, тем более на уровне продакшена. Обрастет костылями, биндингами на Си (еще больше чем сейчас) и захлебнется, как и предыдущие мамкины убийцы сикрестов.
Вот это подходит. Спасибо.
Ух ты, адекват в /pr/
Ну почему, джава и шарп тоже задумывались убийцами крестов и таки преуспели в этом - теперь на крестах пишут только системщину.
>но на деле временный выпердыш
Ух ты, у нас человек из будущего, который пришел сказать, что сикресты вечны. Ставишь жопу, что кресты проживут хотя бы 200 лет? Определи точные границы, когда заканчивается "временный" и начинается "вечный".
Нет. Есть некоторые люди, которые ошибочно считают, что Го - это системный яп, но они глубоко ошибаются. Ничего против Го не имею, отличный инфраструктурный ЯП для девопса и микросервисов, у него есть своя ниша и он ее занял, но этот язык не является системным хотя бы потому, что у него есть garbage collector, но это, естественно, не единственная причина.
Системщина - это Си и кресты уже много лет, были, есть и будут. Спросишь почему? Потому что создать им замену в их области применения практически нереально, должен произойти фурор и открытие, наподобие тому, что произошло между Ассемблером и Си в своё время (Си сотворил революцию в мире программирования в свое время, которая позволила вывести всю индустрию на новый, ранее неизведанный уровень), что в наши дни имеет шансы 1 к охуилярду. Прибавь к этому тонну легаси, все известные и неизвестные ОС, инфраструктуру, количество специалистов и тонну софта, которые в данный момент пишутся и будут писаться на Си и крестах. Вытеснить такое практически невозможно, во всяком случае в мире, где компьютеры построены по нынешним технологиям.
Что получаем из этого? На Си и крестах как писали, так и будут писать системный софт, ОСи и лоу-лвл либы на всех уровнях, а Раст останется на уровне любителей эзотерики.
Пока компьютеры имеют нынешнюю архитектуру - вечны.
Гипотетически возможный сценарий смерти Си и крестов на уровне системщины - выход квантового компьютера за пределы прототипа и тотальный переход человечества на принципиально новую компьютерную технологию, но это повлечет смерть всех языков, это повлечет даже смерть современной криптографии, блять!
>>59882
Джава задумывалась как неебически портативная версия крестов, правда более медленная. А шарп задумывался как убийца джавы, а не крестов, в чем он явно не преуспел, а лишь жидко дал в рейтузы. Я не люблю джаву и если сравнивать ее с шарпом, то как ЯП он больше мне импонирует, но все же от правды не убежишь.
Джава поначалу планировался как суперуниверсальный ЯП, на котором хотели писать даже эмбедщину, в чем тоже жестко обосрались. Если Си - строгая системщина, то кресты активно юзают еще и в геймдеве и хайлоудах. Везде, где нужна ебейшая производительность. В итоге джава заняла нишу в кровавом энтерпрайзе и в мобилках, откуда ее потихоньку вытесняет Котлин, а потом обоих вытеснит макакаскрипт (пара-тройка лет и веб просочится в мобилки еще сильнее и пустит там корни). Кресты тем временем где были (системщина, включая эмбеддед, геймдев и хайлоуд), там и остались. Это их стихия и их область, откуда их выбить практически нереально.
Настоящий системный язык только Си, без плюсов. Он всегда будет в какой-то своей сфере применения.
А вот кресты теснят и сильно, потому что они очень тяжеловесные и ограниченные, Go/Rust как раз занимают нишу между Си и разными питонами с JS.
Rust/C++ как раз занимают нишу между Си и разными питонами с JS и говном.
Кресты "ограниченные", блять, ага. Как раз-таки проблема этого языка (парадоксально, но факт, что это проблема, а не плюс) в том, что этот язык имеет НЕОГРАНИЧЕННЫЕ возможности. Язык, где ты можешь ебать байтики, писать инлайн ассембли, разрабатывая ядра ОС и прошивки, при всем при этом есть возможность писать абстракциями из высокоуровневых япов, так как у тебя есть полноценный ООП, шаблоны (которые Тьюринг-полные и через которые можно реализовать бесплатный по рантайму полиморфизм), STL с КУЧЕЙ структур данных для самых разных целей, у тебя, ебаный в рот, есть даже фичи из функциональщины в виде лямбд, мать твою за ногу! Scalability этого языка НЕОБЪЯТЕН, в нем реализованы все возможные и невозможные парадигмы программирования. Да, огромные проекты долго компилятся, но все это для того, чтобы в рантайме прога не проседала и не сосала хуй, так как кресты используются для разработки высокопроизводительных программ. Go не имеет ничего общего с крестами в плане области применения, а Раст не сможет свергнуть кресты, потому что по сравнению с крестами, Раст - костылированная ограниченная поделка.
upd - проблема неограниченности в том, что за такую мощь приходится платить, и эта плата - сложность языка. Чтобы писать качественный софт на крестах и уметь его дебажить - нужны скиллы. Но пока собаки лают, караван идет, и 99% компаний по всему миру, выбирая между растом и крестами, выберут кресты по ряду очевидных причин. В проде никто шило на мыло менять не собирается, Раст не решает какую-то глобальную проблему, не творит революцию, как это было в случае с Си в свое время, засим и причин повально на него переходить попросту нет. И это происходило со всеми мамкиными убийцами сикрестов. Они либо занимали совершенно другие ниши, либо подыхали.
Даже для самых упоротых фанатов даже не стоял вопрос об использовании этого недоразумения для чего-либо серьезного
А по-моему новые проекты чаще выбирают раст чем кресты. Ну а легаси переписывать да, пока не спешат.
вроде жужл в фуксии его как использовать будет
крестовик, порвался, несите нового лол
Щас бы мертвый цепепе за язык считать, на нем бля уже никто не пишет, только какой-то ссаный легаси на нем остался и все, че ты несешь бля
Люди какие-то другие проблемы решают, неужели иных проблем-то нет?
>>59587
>Удобна же
Можно кучу говна натащить под таким предлогом, мне, например, опускание (не каламбур) типов не нравится (кроме времени жизни - с этим всё ок), у чувака выше IDE их даже заполняет, в редакторе без такой возможности в итоге приходится самому угадывать какие там типы.
>Ты ещё не видел свидетелей отсутствия точки с запятой у которых точка с запятой в конце выражений сразу делает язык неюзабельным говном.
Вот этот момент не дошёл до меня, в чём суть?
>Покажи мне ОС, написанную на крестах.
Симбиан в свое время был полностью написан на плюсах, дрова винды и макоси написаны преимущественно на плюсах (ядро на Си).
В фуксии есть салат из языков, где имеет место быть и плюсам.
мимоанон
>Там на подходе 23 стандарт.
А в 2018 вышел очередной стандарт языка Фортран. И да, на нём до сих пор пишут.
Что не так? Семейство NT точно написано на C. Может какие-нибудь древние 3.11 и были на паскале, может нет, но это было давно и три семейства 3.1/95-ME/NT-XP-10 разрабатывались независимо.
Ооо, еблан тупорылый, все ясно. Приятного времяпровождения в гугле, если заморочишься, то поймешь как сильно ты обосрался, лол
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=deacd51e2896b4d9364aaf4ce249c2a9
если просто позаимствовать два поля компилятор же не ворчит
> Люди какие-то другие проблемы решают, неужели иных проблем-то нет?
А чего там решать? Есть древний RFC и уже почти готовая имплементация (правда пока что только try-блоков с ok-wrapping, а не целых функций) и в целом единственное что мешает этой имплементации уйти в стейбл вопрос "Нужен ли ok-wrapping вообще или нет?". Хотя на самом деле есть ещё второй вопрос и выводом типов - нужно ли по умолчанию делать так чтобы try-блок отдавал result и что делать если тип error вывести невозможно, но он нигде и не используется - игнорировать или выводить ошибку - https://github.com/rust-lang/rust/issues/31436#issuecomment-614735806
> Вот этот момент не дошёл до меня, в чём суть?
В расте точка с запятой имеет важное значение и некоторым это не нравится, потому что они привыкли писать код без неё.
Может. У раста минимальная единица для проверок borrow-checker'а - это структуры. Даже если ты взял поле структуры, компилятор всё равно будет считать что ты взял для редактирования всю структуру. В целом решение этой проблемы не очень простое (и скорее всего значительно усложнит сам язык), но разрабам известно о ней: https://smallcultfollowing.com/babysteps/blog/2018/11/01/after-nll-interprocedural-conflicts/
увы, тогда костылить
Ты статью прочитай. Внутри одной функции да, может работать и с отдельными полями. Но сама функция получает &self, т.е. структуру в целом и компилятор не осилит понять что из структуры она использует только некоторые поля. Потому статья и называется "Interprocedural conflicts". И одно из решений проблемы - ручной инлайн функций, чтобы использование структуры было в пределах одной функции.
У него в примере функция получает именно &self:
fn do_something(&self) {
потому борроу чекер и жалуется на всю структуру, хоть функция и использует только self.c.
Всё так. Но компилятор умеет разбивать владение полей структуры, просто получается у него не идеально и не везде.
На самом деле это сделано специально (что время жизни полей структуры отслеживаются только внутри блока). Как вариант можно передавать вместо ссылки на саму структуру ссылку на поле, либо выносить связанные данные в отдельную структуруи переносить функции в их имплементации (например в случае того кода сделать так: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d143998f8975de1086059f0928882196 ).
Просто представь как просто можно было бы сломать обратную совместимость API (поскольку захват нового поля по сути ломает его, а это можно сделать и случайно, ведь синтаксиса для указания какие поля функция может захватывать нет). Плюс это значительно усложнило ABI раста, поскольку все поля которые функция захватывает нужно как-то указывать.
Крутить структы не воспринимая их как единый объект звучит рокетсаенсно
Если пишешь код с нуля или используешь растовские библиотеки, то естественно всё будет норм. А вот как начнёшь ебаться с FFI, то сразу увидишь всю боль. Где-то читал, что нормальные биндинги для вейленда практически невозможно сделать потому что там структура сначала удаляется из памяти, а потом программе приходит уведомление мол ваша структура была удалена, не используйте её, плиз, что с т.з. раста моментальный UB.
>The main issue seems to be the fact that wayland "resources" - stuff like keyboards and monitor connections - can be removed at any time by the user by just unplugging the video cable. Wayland posts a callback when this happens, but memory like this that could just get deleted at any point is obviously not safe and is not allowed by rust.
>but memory like this that could just get deleted at any point is obviously not safe
То есть вайланд тоже является небезопасным, как и иксы. При этом ничего не умеет.
c-way
Вот тут-то раст и приходит на помощь: https://www.redox-os.org/
У всех не-мейнстримовых операционок есть фатальный недостаток: разработчики железа ебали в рот писать под них драйвера. Потому-то андроид и сделан на базе линуха, что в ядре уже почти всё поддерживалось.
Я больше верю в то, что ядро линуха частично перепишут на расте, чем в шансы редокса. Хотя, orbtk отдельно уже сорт оф взлетел, судя по вакансии выше.
>У всех не-мейнстримовых операционок есть фатальный недостаток: разработчики железа ебали в рот писать под них драйвера.
И не нужно, ведь безопасных операционок общего назначения среди них нет. За исключением недавно появившейся redox, про существование которой они тупо не в курсе.
И чем редокс безопаснее остальных ос?
вобще не понимаю почему раст позиционируется как супер безопасный язык
Типа из-за борроу чекера.
На деле в ОС, как и в любом другом не хэллоу-ворлде, написанном на расте, будет ДОХУЯ ансейф блоков. И не просто ДОХУЯ, а Д О Х У Я. Использование ансейф блока убирает то самое микропреимущество перед си и крестами в плане безопасности памяти. А в виду специфики низкоуровневого пердолинга, а написание ОС им изобилует, абузить ансейф блоки придется ой как дохуя. По этой самой причине Раст - мертворожденный язык, по крайней мере на мировом уровне он не взлетит и никто с Си и крестов перекатываться на раст не будет. И да, Раст не умеет предотвращать все виды состояния гонок, которыми изобилует любая ОС, даже если гипотетически в ОС не было бы ансейф блоков вообще, что на практике невозможно.
наивный переРАСТ... Сколько "убийц" Си и крестов было, видали таких, потом такие по весне оттаивали.
D, Cyclone, Vala, Limbo, BitC - продолжать? Бьюсь об заклад, что кроме D, ты о других языках и не слышал, верно?:-) Твоя ржавая поделка тоже будет скоро на помойке, наивный дурачок, думающий, что Си и кресты можно убить, лол! Отсутствие безопасности памяти - это МАСТХЭВ для языка с ТОПОВОЙ производительностью, как ты ни крути и как в свое ржавое очко ни долбись, раст костылирован от и до, и имеет ансейф не просто так, потому что без ансейфа ты напишешь максимум хэллоуворлд. И да, не спеши искать мне поделки переРАСТов аля "3к строк кода и ни одного ансейфа!", там куча небезопасных либ в биндингах как минимум. СОфт системного уровня на Расте без ансейфа не может быть написан, засим это говно нахуй никому не нужно. Если повезет, то займет нишу на более высоком уровне где-то на уровне Го, и то не факт. В системщине у этого языка, как и у любого другого кококоубийцы, нет абсолютно никаких шансов. Мир компьютерных технологий принадлежит Сям и крестам, он полностью построен на них.
блджад svg же
Jesus, очередной свидетель "ансейфы = C".
> Использование ансейф блока убирает то самое микропреимущество
Как раз существование ансейф блоков - это основное преимущество перед C(++), потому что в расте ты сразу видишь и изолируешь потенциально небезопасное поведение. А в С(++) у тебя ВЕСЬ КОД это небезопасное поведение, которое может сломаться в абсолютно любом месте.
> низкоуровневого пердолинга
Да на железе вообще сложно писать надежный код, ну устроено так оно, ты не открыл Америку. Вот только раст позволяет тебе сделать некоторое количество базовых абстракций, скрыть под ними весь ансейф, и дальше уже работать с нормальным кодом. А не "так, я получил указатель, который прошел через 20 фунций, буду мольиться, чтобы никто больше туда не записал ничего".
> Раст не умеет предотвращать все виды состояния гонок
Я тебе больше скажу - он их никогда и не должен был предотвращать в общем случае. Максимум - data races, и их он прекрасно отлавливает, а если уж ты решил deadlock на мьютексах устроитьт, ну, ССЗБ (хотя в parking_lot есть какой-то детект deadlock'ов).
>>60758
> Vala
> убийца C
Ну, я не уверен, что с тобой имеет смысл вообще разговаривать далее, да. Ты вообще не понимаешь предмет разговора, и походу единственное, что ты можешь - это выделать капсом слово РАСТ. Так что удачи, держись там, хорошего настроения, а господа растоебы пойдут писать годные штуки за 300к/сек.
А как borrow checker предотвращает переполнение кучи? Размер буфера на куче ведь неизвестен во время компиляции, а рантайм чеков у раста вроде нет
речь про динамические массивы, чтобы уточнить. Размер которых определяется в рантайме и может меняться в течение исполнения программы
Как ваще боров чекер может относиться к переполнению кучи ты о чем
Есть мнение, что никак (да и borrow checker тут не при чем). Тут https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.alloc пишут, что при ошибке вернется 0:
> Returns a pointer to newly-allocated memory, or null to indicate allocation failure.
Видимо при заполнении кучи просто вылетит паника:
> Implementations are encouraged to return null on memory exhaustion rather than aborting, but this is not a strict requirement.
Вообще borrow checker про другое - чтобы гарантировать отсутствие data races.
ой, я обосрался с БЧ, ну я пока не знаю толком раст, поэтому простительно
Не суть, короче, перефразирую.
Есть буффер в куче. Его размер - 10 байт, но этот размер известен только во время рантайма. А тут хуяк, я записываю 11 байт в массив на куче. Как Раст предотвратит это, если весь анализ границ в статике, насколько я понял?
То, что ты написал про allocation failure, не относится к моему вопросу никак. Переполнение кучи - это когда кусок памяти на куче переполняется и перезаписывает соседний кусок в памяти, где могут храниться указатели на функции и прочие интересные данные.
в расте [T] это fat pointer на кусок памяти, поэтому будет проверка границ массива и panic
а если указатели перекастовывать как нибудь это уже unsafe, сам виноват будешь
а как ещё?
while i < stroka.len() { ... }
len() будет каждый раз при сравнении вычисляться или только один раз? Как это проверить?
Один раз. И часто оно не вычисляется, а просто читает поле (или вызывает метод вложенной структуры, но при компиляции это всё схлопывается, так что тоже самое).
https://doc.rust-lang.org/src/alloc/vec.rs.html#1335
cursive , если что
660x426, 0:25
cursive , если что
>warning: the function has a cognitive complexity of (27/25)
Сразу видно для лошков из nodejs язык.
На винде с таргетом x86_64-pc-windows-gnu отлично, с x86_64-pc-windows-msvc не работало раньше (clion2019.3), теперь должны были починить (clion2020.1), но я не проверял.
На линуксе всё искаропки работает.
И там и там с thumbv7em-none-eabihf для cortex-m4 через blackmagic probe работает норм.
Очень вам благодарен, сударь
VScode + rust-analyzer или IntelliJ, потому что лучше этого сейчас ничего нет.
Если это работает именно так как описано, то это пиздец, и на Си это написать тоже нереально. Что, у тебя посередине коллбека удалился объект и ты даже не можешь это проверить? Это не может так работать.
Поставил WSL + vscode.
Потому что ты ещё не обучен ебать байты как надо и не понимаешь всей стоимости аллокаций. У нормального человека
fn read_line(&mut self, buf: &mut String) -> io::Result<usize>;
работает намного быстрее, чем
fn read_line(&mut self) -> io::Result<String>
Не, я как раз с сишки пришёл, понимаю, что это быстрее, но думал что для раста это менее важно.
А какая разница-то? Просто при передачи ссылки можно сделать сразу кучу оптимизаций:
1) При создании строки заранее аллоцировать некоторое количество байтов, чтоб в некоторых случаях можно было прочитать данные без реаллокации.
2) Если read_line вызывается несколько раз, то есть шанс, что он сработает без реаллокации при 2+ чтении, если свободного места в строке хватит для данных.
С возвратом строки такие оптимизации не сработают.
Вы видите копию треда, сохраненную 2 августа 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.