хочу что-то такое:
struct A(i32, u32);
let a = Arc::new(A(0, 5));
let b: Arc<i32> = a.project().0;
Очевидно нет.
почему очевидно?
Задумайся, как Arc устроен в памяти. Это одна аллокация, которая выглядит так: счётчик | данные В твоём случае счётчик | i32 | u32 Если ты таким образом получишь u32, то слева от него будет не счётчик, а i32
у нас же в памяти это лежит как |arc-data|i32|u32| то есть я могу в теории инкрементнуть arc-data но при этом разрешать по указателю ходить только в i32
Это бы хоть как-то работало для «левого» в памяти поля, если бы ты знал, какое из них левое. Но ты не знаешь.
Следующая проблема у тебя возникнет на дропе. Если ты последним дропаешь вот такой вот «частичный» Arc, то он попытается дропнуть 12 байт вместо 16 и хоба UB.
Не очевидно, что мешает двум разным сущностям иметь один контрольный блок
Ты дропнул последний Arc, тебе нужно деаллоцировать память. Сколько памяти ты деаллоцируешь?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4335d55ae7a977be3ff884454c982a9b
я бы просто таскал с собой замыкание и всё, зеро кост же 😜
Можно ArcProject параметризовать типом замыкания. Должно оптимизироваться
Обсуждают сегодня