【问题标题】:Trait convertion into another trait to use in dyn variable将特征转换为另一个特征以在 dyn 变量中使用
【发布时间】:2022-11-04 17:22:20
【问题描述】:

我有像let t1: &dyn T1let t1: Box<dyn T1> 这样的变量,或者来自外部库的这样的变量。我想将此变量用作另一个特征。所以,我有代码

fn another_function(let t2: Box<dyn T2>);

let t1: Box<dyn T1> = run_external_function();
another_function(t1);

如何将 Rust 中的特征转换为另一个特征?例如

trait T1{}
trait T2{}
impl T2 for dyn T1{}

let t1: &dyn T1 = ;
let t2: &dyn T2 = t1;

我在类似的code 中尝试过,但失败并出现错误

预期特征T2,找到特征T1

【问题讨论】:

标签: rust


【解决方案1】:

无法将 dyn T1 转换为 dyn T2。想一想:dyn T1 包含数据,但 dyn T2 还必须包含类型,即 vtable。我们什么时候存储它?通常,它存储在引用中,但这里没有引用!

完成这项工作的一种方法是将T2 用于&amp;'_ dyn T1 而不是dyn T1

impl T2 for &'_ dyn T1 {}

let t1: &dyn T1 = ...;
let t2: &dyn T2 = &t1;

现在第一个引用存储T1 的vtable,第二个引用存储T2 的vtable。

【讨论】:

  • > 无法将 dyn T1 转换为 dyn T2。我的意思是,我们可以通过添加新的 vtable 并将旧的引用保存在变量上,将 &dyn T1 转换为 &dyn T2。编译器给出同样的错误:rust.godbolt.org/z/hd3T8oMoe
  • @SuvorovIvan 我们将在哪里保存T1 的vtable?
  • 如果我理解它是如何工作的,例如,如果我们有通常的变量(不是 trait),我们在它旁边创建 vtable,并保留这个变量,所以我们有对(vtable,variable)。如果我们有&dyn T,这就像一个指针,所以我们在它旁边创建vtable并保持成对(vtable,pointer_to_some_object)。怎么了?
  • @SuvorovIvan 问题是我们需要存储虚表。如果我理解正确,您想存储一个三元组:数据指针、T1 的 vtable 和 T2 的 vtable。但是,&amp;dyn T2 的大小已经设置为两个usizes,而不是三个,我们无法更改它(例如,我们可能需要将它传递给一个期望它为两个的函数)。
  • 不是为什么?我们将变量转换为 dyn T2,这意味着我们不再需要 T1 类型。是的,t2 变量仍然有 T1 的 vtable,但是这个 vtable 隐藏在 ptr 后面。所以,我想,会有下一个近似值:t2 == (T2 vtable, *(T1 vtable, *real_object))。但是嵌套对仍然是对象,没关系
猜你喜欢
  • 1970-01-01
  • 2017-05-23
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 2018-10-20
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多