- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在下面的代码中,不可能从对实现相同特征的动态大小类型的引用中获得对特征对象的引用。为什么会这样呢?如果我可以同时调用trait方法,那么&dyn Trait
和&(?Sized + Trait)
之间到底有什么区别?
实现FooTraitContainerTrait
的类型可能例如具有type Contained = dyn FooTrait
或type Contained = T
,其中T
是实现FooTrait
的具体类型。在这两种情况下,获取&dyn FooTrait
都是微不足道的。我想不出另一种情况,这是行不通的。在FooTraitContainerTrait
的一般情况下,为什么这不可能呢?
trait FooTrait {
fn foo(&self) -> f64;
}
///
trait FooTraitContainerTrait {
type Contained: ?Sized + FooTrait;
fn get_ref(&self) -> &Self::Contained;
}
///
fn foo_dyn(dyn_some_foo: &dyn FooTrait) -> f64 {
dyn_some_foo.foo()
}
fn foo_generic<T: ?Sized + FooTrait>(some_foo: &T) -> f64 {
some_foo.foo()
}
///
fn foo_on_container<C: FooTraitContainerTrait>(containing_a_foo: &C) -> f64 {
let some_foo = containing_a_foo.get_ref();
// Following line doesn't work:
//foo_dyn(some_foo)
// Following line works:
//some_foo.foo()
// As does this:
foo_generic(some_foo)
}
foo_dyn(some_foo)
行会导致编译器错误
error[E0277]: the size for values of type `<C as FooTraitContainerTrait>::Contained` cannot be known at compilation time
--> src/main.rs:27:22
|
27 | foo_dyn(contained)
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `<C as FooTraitContainerTrait>::Contained`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where <C as FooTraitContainerTrait>::Contained: std::marker::Sized` bound
= note: required for the cast to the object type `dyn FooTrait`
最佳答案
可以将这个问题简化为以下简单示例(由于turbulencetoo):
trait Foo {}
fn make_dyn<T: Foo + ?Sized>(arg: &T) -> &dyn Foo {
arg
}
T
是Sized
,则编译器静态地知道应使用哪个vtable创建特征对象; T
是dyn Foo
,则vtable指针是引用的一部分,可以直接复制到输出中。 T
是不是dyn Foo
的某种非大小型类型,即使特征是对象安全的,impl Foo for T
也没有vtable。 self
指针是精简指针。当您在
dyn Trait
对象上调用方法时,将使用vtable指针查找函数指针,并且仅将数据指针传递给该函数。
trait Bar {}
trait Foo {
fn foo(&self);
}
impl Foo for dyn Bar {
fn foo(&self) {/* self is a fat pointer here */}
}
impl
有一个vtable,则它必须接受胖指针,因为
impl
可能会使用
Bar
的方法,这些方法是在
self
上动态调度的。
Bar
vtable指针存储在&dyn Foo
对象中,该对象的大小只有两个指针(数据指针和Foo
vtable指针)。 dyn Bar
实现了
Foo
,也无法将
&dyn Bar
转换为
&dyn Foo
。
impl Foo for [i32]
也有相同的限制。
CoerceUnsized
(仅在Rust 1.36以后的夜晚)来表示“必须对
&dyn FooTrait
强制”的边界。不幸的是,我看不到如何在您的情况下应用此功能。
str
)的引用。 关于generics - 为什么 `&(?Sized + Trait)`无法转换为 `&dyn Trait`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61653006/
我对下面的生命周期发生了什么感到困惑: struct Foo{} impl Foo { fn foo(&self, _s: &str) {} } fn main() { let foo
这个问题在这里已经有了答案: How to convert a boxed trait into a trait reference? (2 个答案) 关闭去年。 我正在尝试获取 &dyn T来自B
这个问题在这里已经有了答案: Why doesn't Rust support trait object upcasting? (4 个回答) 1年前关闭。 我有一个库需要实现特定特征( TQDisp
我有一个接收 Box 的函数并需要将其转换为 Rc在线程内共享只读所有权。 用Box一些T: Sized ,我们可以做到Rc::new(*my_box) ,但不幸的是that doesn't work
我可以接受 Box 吗?在接受 Box 的地方?如果是,如何?如果不是,为什么,还有比以下示例更优雅的方法吗? #![allow(unused)] use std::error::Error as S
这个问题在这里已经有了答案: Why doesn't Rust support trait object upcasting? (4 个回答) 2年前关闭。 如果我有 Box , 我可以返回 &dyn
我无法将参数传递给 fn。 trait T {} struct S { others: Vec>> } impl S { fn bar(&self) { for o i
在我的程序中,在辅助线程上执行了一些操作及其结果:Result>被发送回主线程。这是非常合理的错误有 Send要求,所以实际类型是Result> .我还加了 Sync能够使用 Box from方法(仅
我有一个 Vec>作为输入,我想将其元素存储在 Vec>> .最好的方法是什么? 我试过: use std::cell::RefCell; use std::rc::Rc; trait Trait {
use std::sync::Arc; pub type A = Arc Result + Send + Sync>; pub struct B { a: A, } 给 Compilin
这个问题在这里已经有了答案: Why doesn't Rust support trait object upcasting? (4 个回答) Can I cast between two trait
读完the subtyping chapter of the Nomicon ,我无法理解类型参数的协方差。特别是对于 Box类型,描述为:T is covariant . 但是,如果我写这段代码:
我尝试在 vs 包管理器中安装第三方包时反复出现此错误, Unable to resolve dependency 'openssl.v120.windesktop.msvcstl.dyn.rt-dy
我有以下简化代码。 use async_trait::async_trait; // 0.1.36 use std::error::Error; #[async_trait] trait Metric
我有以下简化的代码。 use async_trait::async_trait; // 0.1.36 use std::error::Error; #[async_trait] trait Metri
我正在尝试在线程之间共享一个函数,可以用另一个函数调用它: fn main() { let on_virtual_tun_write = std::sync::Arc::new(|f: &dy
我最近看过使用dyn关键字的代码: fn foo(arg: &dyn Display) {} fn bar() -> Box {} 这个语法是什么意思? 最佳答案 TL; DR:这是用于指定特征对象类
我正在创建HashMap>。我可以创建HashMap并插入一个实现MyTrait的结构,但是当我检索MyTrait并尝试使用它时,编译器向我提示: error[E0161]: cannot move
我正在阅读一些代码,它有一个 consume使我可以通过自己的函数 f 的函数. fn consume(self, _timestamp: Instant, len: usize, f: F) ->
我最近看到使用 dyn 关键字的代码: fn foo(arg: &dyn Display) {} fn bar() -> Box {} 这个语法是什么意思? 最佳答案 TL;DR:这是一种用于指定tr
我是一名优秀的程序员,十分优秀!