如何将引用元组转换为元组引用? [英] How to convert a tuple of references to a reference of a tuple?
问题描述
我想将引用元组(都是对同一结构成员的引用)转换为元组的引用.
I'd like to convert a tuple of references (which are all references to members of the same struct) to a reference of a tuple.
我试图以各种方式胁迫他们,但如果不进行克隆我就无法做到.
I've tried to coerce them in various ways, however I wasn't able to do it without cloning.
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
的类型为 &(Bar, Bar)
给定 a
的类型为 &Foo代码>.
I expect b
to be of type &(Bar, Bar)
given a
is of type &Foo
.
推荐答案
这不可能.
引用引用到一个值.你希望有一个 &(Bar, Bar)
但内存中没有任何地方有 (Bar, Bar)
的 2 元组.你不能引用不存在的东西.
A reference refers to a value. You wish to have a &(Bar, Bar)
but there is nowhere in memory that has a 2-tuple of (Bar, Bar)
. You cannot refer to something that does not exist.
&(A, B)
和 (&A, &B)
的内存布局根本不兼容,所以你也不能使用不安全的 Rust 技术.
The memory layouts of &(A, B)
and (&A, &B)
are fundamentally incompatible, so you cannot use unsafe Rust techniques either.
在这种特殊情况中,您可能能够使用不安全的 Rust 将您的 &Foo
直接转换为 &(Bar, Bar)
,但是...
In this particular case, you might be able to use unsafe Rust to convert your &Foo
directly to a &(Bar, Bar)
, but...
- 它要求元组结构和元组的布局相同;我不知道这是保证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 — 事实上,引用明确指出:
元组对其布局没有任何保证.
Tuples do not have any guarantees about their layout.
唯一的例外是单元元组 (()
),它保证为零大小类型,大小为 0,对齐方式为 1.
The exception to this is the unit tuple (()
) which is guaranteed as a zero-sized type to have a size of 0 and an alignment of 1.
这意味着虽然此代码可能会打印出您期望的内容并且 Miri 没有抱怨,但这是未定义的行为.
This means that while this code may print out what you expect and Miri does not complain, it's undefined behavior.
这篇关于如何将引用元组转换为元组引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!