Как безопасно сделать небезопасно?
Я пока не до конца уверен, что я в правильном направлени иду, но вот какая у меня идея:
Мне нужно в новый тред отдавать ссылки только со 'static, а я хочу туда отдать (из метода структуры) ссылку на кусок "себя". Что, очевидно, нарушает 'static, потому что если "себя" сделают drop() по выходу из блока/функции, будет danging pointer, а весь раст строился вокруг того, чтобы такого не было. И нужно именно так сделать.
Задача: сохранить инвариант. Т.е. сделать так, чтобы при drop() себя, отданная ранее в соседний тред ссылка была бы жива. Это традиционная задача AI tetris (https://www.youtube.com/embed/xOCurBYI_gY?start=910&feature=oembed&enablejsapi=1), и она прекрасно решается с помощью bottom type.
impl Drop for Screen{
fn drop(&mut self){
if let Some(..) = self.thread {
println!("Attempt to drop Screen. Looping forever.");
loop{}
}
}
}
Такой подход гарантирует: а) что ссылка жива до конца программы. б) что структуру можно создавать с не 'static lifetime, потому что есть drop().
В самой программе нужно, конечно, выходить не через return:
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => std::process::exit(0),
_ => {}
}
Это была простая часть. А теперь сложная - как бы мне сделать mut slice и slice на один и тот же набор данных, чтобы мне за это не особо много влетело?
stay tuned.
no subject
no subject
Rc и Arc в Rust'е - это базовые примитивы для ресурсов со счётчиками, но я (пока что) считаю себя smart cookie и надеюсь суметь реализовать многопоточный r/w доступ к shared памяти "за так", без дополнительных примитивов. Точнее, используя только relaxed-atomic.
no subject
no subject
pub unsafe fn read(&self) { self.0.read() }и понял что это уже выше моего понимания.
no subject
По-помоему тут unsafe код, потому что если это rw lock, то ты читаешь его минуя лок (что unsafe и, может быть, даже UB, если там запись в параллель идёт).
no subject
no subject
Нулевой элемент тапла или tuplestruct'а.
no subject
1. а x.i сделать можно?
2. а x[0]? А почему?
3. а к элементу массива/слайса так обратиться можно?
no subject
Тапл содержит данные разного типа. Это такая "анонимная структура", к которой ты обращаешься по имени поля. Чтобы не разводить бюрократию, тебе автоматически их генерируют (имена).
Ты не можешь написать
for x in tuple, потому что типы разные. Это структура, и доступ к mytuple.0 мало отличается от доступа к mystruct.foobar.В этом смысле он очень консистентный и логичный.
[] - совсем другая операция. Чтобы не было путаницы с элементами tuple'а их сделали максимально различающимися.
no subject
Он позволяет объявить безтиповую переменную.
В rust нет ничего похожего?
no subject
А что такое безтиповая переменная?
no subject
func main() { var a interface{} a = 5 fmt.Println(a) a = "string" fmt.Println(a) }no subject
Это выглядит как динамическая типизация. В расте она есть (dyn), но она требует таскать указатель на объект, чтобы использовать его "не глядя". Я эту область совсем не трогал. Вот что тут пишут: https://doc.rust-lang.org/rust-by-example/trait/dyn.html
Но оно всегда медленее, чем compile-time типизация.
Твой пример на rust выглядит так:
Секрет в том, что это две разные перменные с разным lexical scope. Как только второй let выполняется, первая переменная больше не существует.
no subject
Как в rust сделать так:
func main() { m := make(map[int]interface{}) m[1] = 1 m[2] = "two" m[3] = 3.14 for i, val := range m { fmt.Printf("m[%d] == %v\n", i, val) } }no subject
no subject
В rust'е ничего нельзя сделать без unsafe. Даже выйти из программы. Суть unsafe не в том, что это "плохо", а в том, что это "опасно" и программисту требуется пристально думать в этих местах. В замен, в остальных местах можно думать меньше (и не о том), и Rust проследит за тем, чтобы не было косяков.
Т.е. снизу unsafe rust на 100% (большинство типов - Vec, Slice, Hash и т.д. содержат внутри unsafe-код). Они тщательно делают unsafe код безопасным (компилятор это не может, тут нужен человек и мозги), и потом отдают наружу уже safe-версии себя, которые творят магию (включая, reference counting, игрища с ownership для элементов внутри массива и т.д.).
Идея в том, что unsafe - это специальный маркер кода (примерно, как приватные члены в классе), позволяющий лучше различать момент, когда лифтёр лезет в шахту вне кабины лифта от ситуаций, когда кто-то хотел с 3 на 2 этаж (и вовсе не предполагал получить лифтом по голове).
no subject
Это тебе "джаст фо фан" интересно сделать всё правильно. А я уверен, что найдётся уйма программистов, которые по какой либо из причин (сроки поджимают, лень разбираться, "я достаточно умный и понимаю что делаю") в этом месте обернут код в unsafe и не будут париться.
Понимаешь, если в обычном Си/СиПиПи все знают и уже привыкли - "это язык для стреляния себе в ногу, поэтому нужно быть внимательным и не расслабляться", то в расте на слуху "это специальный язык, тут нельзя выстрелить себе в ногу". Но когда начинаешь разбираться - выясняется что выстрелить можно. Более того - иногда прям хочется обернуть всё в один большой unsafe и перестать испытывать анальную боль, потому что компилятор постоянно бъёт по рукам (руки и анальная боль в одной фразе - это не случайно).
Да, я понимаю что по другому сделать нельзя, скорее всего, если мы делаем язык на котором можно лазить к железу, например. Но блин.
no subject
Я это понимаю, но Rust - это язык, который умеет всё (как С/С++). Его можно пытаться сравнивать с языками, которым нужны runtime-песочницы (тот же Go или Haskell), но тогда надо закрывать глаза на ту часть, которая нужна для написания функции обработки прерывания (naked functions). И на unsafe.
Rust - это C++, из которого выкинули лишнее, сделали разумными дефолты и добавили чуть больше типофашизма (а может уже и нет - C++ развивается). Т.е. С++ развивается по принципу "а можно ещё и вот это", а Rust старается держать некоторую консистентность и разумность.
В целом, как язык высокого уровня он неожиданно скудный, особенно в районе функций, но выразительный (в районе enum'ов и match'ей и for'ов).
Я сейчас на два дня нырнул в unsafe rust (всякие pointer'ы и прочие ужасы) и вынырнув оттуда я начал лучше чувствовать некоторые типы.