如何将引用元组转换为元组的引用?

乔纳斯

我想将一个引用的元组(所有引用都指向同一结构的成员)转换为一个元组的引用。

我试图以各种方式强迫他们,但是如果没有克隆,我是无法做到的。

struct Bar();

struct Foo(Bar, Bar, Bar);

fn main() {
    let a: &Foo = &Foo(Bar(), Bar(), Bar());
    let b: &(Bar, Bar) = &(a.0, a.1);
}
error[E0507]: cannot move out of borrowed content
 --> src/main.rs:7:28
  |
7 |     let b: &(Bar, Bar) = &(a.0, a.1);
  |                            ^^^ cannot move out of borrowed content

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:7:33
  |
7 |     let b: &(Bar, Bar) = &(a.0, a.1);
  |                                 ^^^ cannot move out of borrowed content

我期望b是type,&(Bar, Bar)因为atype是&Foo

Shepmaster

这是不可能的。

引用是指一个值。您希望有一个,&(Bar, Bar)但是内存中没有2个元组的地方(Bar, Bar)您不能引用不存在的内容。

的内存布局&(A, B)(&A, &B)是根本不相容的,所以你也不能使用不安全的防锈技术。


这种情况下,您可能可以使用不安全的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。

这意味着尽管此代码可能会打印出您期望的内容,并且Miri不会抱怨,但这是未定义的行为。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章