Это невозможно.
Ссылка ссылается на значение.Вы хотите иметь &(Bar, Bar)
, но нигде в памяти нет 2-кортежа (Bar, Bar)
.Вы не можете ссылаться на то, что не существует.
Схемы памяти &(A, B)
и (&A, &B)
принципиально несовместимы, поэтому вы также не можете использовать небезопасные методы Rust.
В в данном конкретном случае , вы могли бы иметь возможность использовать небезопасный Rust для преобразования вашего &Foo
напрямую в &(Bar, Bar)
, но ...
- это требует, чтобы расположение структуры кортежа и кортежа было одинаковым;Я не знаю, гарантировано ли 1
- , что требуется, чтобы макет структуры кортежа был плотно упакован так, чтобы вы могли смещаться на размер элемента, чтобы перейти к следующему;Я не знаю, что это гарантировано 1
- это требует, чтобы макет структуры кортежа размещал элементы в том же порядке, в котором они определены;Я не знаю, что гарантировано 1
- вы можете сделать это только для последовательных частей;нет получения первого и третьего элемента
// I copied this unsafe block from Stack Overflow
// without properly documenting why I think this code is safe.
let b: &(Bar, Bar) = unsafe { &*(a as *const Foo as *const (Bar, Bar)) };
println!("{:?}", b);
// I copied this unsafe block from Stack Overflow
// without properly documenting why I think this code is safe.
let c: &(Bar, Bar) = unsafe {
let p = a as *const Foo as *const Bar;
let p = p.offset(1);
&*(p as *const (Bar, Bar))
};
println!("{:?}", c);
1 - Фактически, ссылка явно заявляет :
Кортежи не имеют никаких гарантий относительно их макета.
Исключением является кортеж модуля (()
), который гарантированно имеет тип нулевого размера с размером 0.и выравнивание 1.
Это означает, что хотя этот код может распечатать то, что вы ожидаете, и Мири не жалуется, это неопределенное поведение.