如何将引用元组转换为元组引用? [英] How to convert a tuple of references to a reference of a tuple?

查看:59
本文介绍了如何将引用元组转换为元组引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将引用元组(都是对同一结构成员的引用)转换为元组的引用.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆