Это стандартный подход в расте: прячем все unsafe-операции за безопасным API, которое будет проверять входные данные и убеждаться в том, что никакие инварианты нарушены не будут. Ничего лучшего вы придумать не сможете, если хотите достичь заявленных целей в статье.
Но данная оптимизация в принципе редко применима на практике, это правда. В прикладных программах, очевидно, так никто делать не станет: код становится слишком сложнее. Цена за выигрыш слишком высока, всем плевать на лишние 300кб.
Автор избавился от panic добавив assert_unchecked, что определённо хуже, т. к. последнее в случае ошибки в коде тихо завалит или попортит программу.
Так ошибки не будет в данном коде никогда. Вставка assert_unchecked - это декларация инварианта для структуры S. Структуру S мы можем создать только одним способом - через вызов S::new, который проверяет на корректность входные данные.
Но и он внезапно 30 сентября слился с Гитхаба, перенеся разработку на свой сайт.
Как я понял, к нему в issue понабежали "советчики" как правильно готовить гит, а dotexe1337 это вообще не интересно - он просто пилит vxkex для себя, не позиционируя себя в качестве "professional programmer". Он гитхаб использовал только в качестве системы тикетов об ошибках и облачного хранения кода (а-ля дропбокс). Я думаю, это и является единственной причиной почему проект был заархивирован на гитхабе.
Да, это известный баг. Занятно, что есть простой способ это обойти. После сохранения надо тут же ещё раз сохранить игру в тот же самый файл. После этого простого действия, при загрузке ход пропускаться не будет.
Потому что правила автовывода лайтаймов (lifetime elision) строго определены, и данный случай под эти правила не подходит.
Вот пример кода, где выставление одинакового лайфтайма (времени жизни, ВЖ) во всех местах в функции foo_incorrect не пройдет проверку БЧ (borrow checker):
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=1ce9cb09c241bf12fba2bd33574b24b0
fn main() {
let mut str_mut = "";
let s1 = String::from("str1");
{
let s2 = String::from("str2");
str_mut = foo_incorrect(&s1, &s2); // fail here
// str_mut = foo_correct(&s1, &s2); // will be ok
}
println!("{str_mut}");
}
fn foo_correct<'long, 'short>(a: &'long str, b: &'short str) -> &'long str {
todo!()
}
fn foo_incorrect<'a>(a: &'a str, b: &'a str) -> &'a str {
todo!()
}
Надо понимать, что БЧ выполняет проверку ВЖ для каждой функции отдельно, не заглядывая в тела других использующихся функций. То есть, в примере выше - неважно что будет написано в теле функций foo_correct \ foo_incorrect - проверка ВЖ для функции main от этого никак не изменится: учитываться будут только сигнатуры вызываемых функций.
Если бы для каждой функции анализировались тела всех используемых функций, то время компиляции стремилось бы к бесконечности. Но что хуже - такое поведение вносило бы гораздо больше ошибок из-за неправильного вывода ВЖ. Даже стандартные правила вывода ВЖ иногда приводят к неверному результату, приходится вручную указывать (но это редко).
Компилятор не может знать что вы хотите написать, он может только проверить на корректность написанное.
Управление памятью реализовано через владение (ownership). Компилятор на этапе _компиляции_ анализирует код и сам вставляет вызовы free (условно) в то место, где владелец данных (переменная) выходит из скоупа (то есть гарантированно больше никто не может ссылаться на данные).
Контейнеры с подсчётами ссылок есть, но используются не часто.
Всю статью не читал, осилил только первый наброс про мутабельность, и вот это правильный комментарий.
Ссылки в расте надо интерпретировать именно так:
&mut T - уникальная ссылка. Из этого свойства как раз и вытекает возможность безопасной мутации объекта.
&T - шаренная ссылка. На этот объект может иметь доступ много кто, поэтому в общем случае изменять данные под ней нельзя. Но можно переложить ответственность за контроль корректного доступа (exactly one writer XOR multiple readers) в рантайм с помощью Mutex, RwLock или иных способов Interior Mutability.
К сожалению уже устоявшаяся классическая дискриминация по признаку наличия\отсутствия смартфона. Типа, если нету у тебя смартфона, то ты и не человек вовсе.
Это серверное оборудование, в любом сервере всегда имеется сильный воздушный поток вдоль всего корпуса. Все карты расширения предназначенные для серверов проектируются с учётом того, что хороший обдув будет обеспечен корпусными вентиляторами, соответственно ограничиваются только радиатором на чипах, но это не отменяет необходимость активного охлаждения.
Это стандартный подход в расте: прячем все unsafe-операции за безопасным API, которое будет проверять входные данные и убеждаться в том, что никакие инварианты нарушены не будут. Ничего лучшего вы придумать не сможете, если хотите достичь заявленных целей в статье.
Но данная оптимизация в принципе редко применима на практике, это правда. В прикладных программах, очевидно, так никто делать не станет: код становится слишком сложнее. Цена за выигрыш слишком высока, всем плевать на лишние 300кб.
Так ошибки не будет в данном коде никогда. Вставка
assert_unchecked- это декларация инварианта для структурыS. СтруктуруSмы можем создать только одним способом - через вызовS::new, который проверяет на корректность входные данные.Как я понял, к нему в issue понабежали "советчики" как правильно готовить гит, а
dotexe1337это вообще не интересно - он просто пилит vxkex для себя, не позиционируя себя в качестве "professional programmer". Он гитхаб использовал только в качестве системы тикетов об ошибках и облачного хранения кода (а-ля дропбокс). Я думаю, это и является единственной причиной почему проект был заархивирован на гитхабе.Дополнительные причины почему случилась такая неразбериха с кучей форков и разными коммитами описаны в третьем абзаце:
https://github.com/dotexe1337/VxKex/issues/1#issuecomment-2798345435
Это в вашем моде так? В ваниле это завит от слота: строит тот игрок, который находится выше.
А в турнирном патче, например, сделали псевдорандом.
Да, это известный баг. Занятно, что есть простой способ это обойти. После сохранения надо тут же ещё раз сохранить игру в тот же самый файл. После этого простого действия, при загрузке ход пропускаться не будет.
edition2024 доступен только начиная с 1.85, а вы пытаетесь собрать в 1.83 - естественно он будет ругаться, т.к. не знает как с этим работать.
Какие?
Потому что правила автовывода лайтаймов (lifetime elision) строго определены, и данный случай под эти правила не подходит.
Вот пример кода, где выставление одинакового лайфтайма (времени жизни, ВЖ) во всех местах в функции
foo_incorrectне пройдет проверку БЧ (borrow checker):Надо понимать, что БЧ выполняет проверку ВЖ для каждой функции отдельно, не заглядывая в тела других использующихся функций. То есть, в примере выше - неважно что будет написано в теле функций
foo_correct\foo_incorrect- проверка ВЖ для функцииmainот этого никак не изменится: учитываться будут только сигнатуры вызываемых функций.Если бы для каждой функции анализировались тела всех используемых функций, то время компиляции стремилось бы к бесконечности. Но что хуже - такое поведение вносило бы гораздо больше ошибок из-за неправильного вывода ВЖ. Даже стандартные правила вывода ВЖ иногда приводят к неверному результату, приходится вручную указывать (но это редко).
Компилятор не может знать что вы хотите написать, он может только проверить на корректность написанное.
Так вы в примере не используете
fooповторно вне замыкания. Речь именно об этом.А зачем тогда тащить C++, если в итоге будет C с классами? Так оно и так плюс-минус присутствует в коде ядра, местами. Если я ничего не путаю.
UPD: Ради контейнеров умных ссылок - ну не знаю, как будто бы и не стоит овчинка выделки.
Управление памятью реализовано через владение (ownership). Компилятор на этапе _компиляции_ анализирует код и сам вставляет вызовы free (условно) в то место, где владелец данных (переменная) выходит из скоупа (то есть гарантированно больше никто не может ссылаться на данные).
Контейнеры с подсчётами ссылок есть, но используются не часто.
Примеров, подтверждающих эти возгласы мы конечно же не увидим.
Автору надо ник поменять, а то его тёмное прошлое пестрит даже без резюме. /s
Всю статью не читал, осилил только первый наброс про мутабельность, и вот это правильный комментарий.
Ссылки в расте надо интерпретировать именно так:
&mut T- уникальная ссылка. Из этого свойства как раз и вытекает возможность безопасной мутации объекта.&T- шаренная ссылка. На этот объект может иметь доступ много кто, поэтому в общем случае изменять данные под ней нельзя. Но можно переложить ответственность за контроль корректного доступа (exactly one writer XOR multiple readers) в рантайм с помощьюMutex,RwLockили иных способов Interior Mutability.К сожалению уже устоявшаяся классическая дискриминация по признаку наличия\отсутствия смартфона. Типа, если нету у тебя смартфона, то ты и не человек вовсе.
Я вот понять не могу, откуда это утверждение взялось, что раст каждый релиз ломается?
Это серверное оборудование, в любом сервере всегда имеется сильный воздушный поток вдоль всего корпуса. Все карты расширения предназначенные для серверов проектируются с учётом того, что хороший обдув будет обеспечен корпусными вентиляторами, соответственно ограничиваются только радиатором на чипах, но это не отменяет необходимость активного охлаждения.
Вы так говорите, как будто действительно верите что Земля не плоская )
Я так понимаю, Бобрандреску это отсылка к А. Александреску.
Ну, с номера вашей бабушки позвонить уже не смогут, например.
Эта система режет только звонки с подменных номеров, а не те звонки про которые вы подумали.