Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 我可以用trait对象进行类型内省,然后对其进行降级吗?_Rust - Fatal编程技术网

Rust 我可以用trait对象进行类型内省,然后对其进行降级吗?

Rust 我可以用trait对象进行类型内省,然后对其进行降级吗?,rust,Rust,我有一个Trait的集合,一个迭代它并执行某些操作的函数,然后我想检查实现器类型,如果它是Foo类型,则将其向下转换并调用一些Foo方法 基本上,类似于围棋的东西 四处搜索我找到了,但它只能在静态类型上实现 要帮助演示我想要的内容,请执行以下操作: let vec: Vec<Box<Trait>> = // for e in vec.iter() { e.trait_method(); // if typeof e == Foo { // le

我有一个
Trait
的集合,一个迭代它并执行某些操作的函数,然后我想检查实现器类型,如果它是
Foo
类型,则将其向下转换并调用一些Foo方法

基本上,类似于围棋的东西

四处搜索我找到了,但它只能在
静态类型上实现

要帮助演示我想要的内容,请执行以下操作:

let vec: Vec<Box<Trait>> = //

for e in vec.iter() {
    e.trait_method();

    // if typeof e == Foo {
    // let f = e as Foo;
    // f.foo_method();
    //}
}
让vec:vec=//
对于vec.iter()中的e{
e、 特征_方法();
//如果类型e==Foo{
//设f=e为Foo;
//f.foo_方法();
//}
}

正如您所注意到的,向下投射只适用于
任何
特征,是的,它只支持
静态
数据。你可以找到最近关于为什么会这样的讨论。基本上,实现任意生命周期的引用的反射是困难的


也不可能(至少到目前为止)轻松地将
任何
与您的定制特征结合起来。然而,最近已经为您的trait创建了一个自动实现
Any
。您还可以找到一些关于它的讨论。

正如您所注意到的,向下投射只适用于
任何
特征,是的,它只支持
静态
数据。你可以找到最近关于为什么会这样的讨论。基本上,实现任意生命周期的引用的反射是困难的


也不可能(至少到目前为止)轻松地将
任何
与您的定制特征结合起来。然而,最近已经为您的trait创建了一个自动实现
Any
。你也可以找到一些关于它的讨论。

这不是一个特定于锈蚀的问题,尽管词汇可能有点不同。解决此类问题的理想方法,不仅是Rust中的Trait,而且是任何语言中的Trait,是将所需的行为(
foo_method
,在您的示例中)添加到抽象接口(
Trait
):

as_any
必须是
Trait
中的方法,因为它需要访问具体类型。现在,您可以尝试对
Trait
Trait对象调用
Foo
方法,如下所示():

if let Some(r)=downcast::(trait\u object\u ref){
r、 foo_方法();
}
要实现这一点,您必须指定所需的类型(
),并使用
if let
处理当引用对象不是
Foo
的实例时发生的情况。除非确切知道具体类型,否则不能将trait对象向下转换为具体类型


但是如果你需要知道具体的类型,trait对象几乎毫无用处!您可能应该改为使用
enum
,这样,如果忽略处理某个变量,就会出现编译时错误。此外,您不能将
Any
与非
静态
结构一起使用,因此如果任何
Foo
可能需要包含引用,则此设计是死路一条。如果你能做到的话,最好的解决办法是在trait本身中添加
foo\u method

这不是一个特定于锈菌的问题,尽管词汇可能有点不同。解决此类问题的理想方法,不仅是Rust中的Trait,而且是任何语言中的Trait,是将所需的行为(
foo_method
,在您的示例中)添加到抽象接口(
Trait
):

as_any
必须是
Trait
中的方法,因为它需要访问具体类型。现在,您可以尝试对
Trait
Trait对象调用
Foo
方法,如下所示():

if let Some(r)=downcast::(trait\u object\u ref){
r、 foo_方法();
}
要实现这一点,您必须指定所需的类型(
),并使用
if let
处理当引用对象不是
Foo
的实例时发生的情况。除非确切知道具体类型,否则不能将trait对象向下转换为具体类型


但是如果你需要知道具体的类型,trait对象几乎毫无用处!您可能应该改为使用
enum
,这样,如果忽略处理某个变量,就会出现编译时错误。此外,您不能将
Any
与非
静态
结构一起使用,因此如果任何
Foo
可能需要包含引用,则此设计是死路一条。如果你能做到的话,最好的解决办法是在特质本身中添加
foo\u方法。

你确定你需要向下投射(应该尽可能避免)?如果您控制
Trait
Foo
,您很可能会避免它。这似乎是
Enum
s的目标场景。@goertzenator您能提供一个示例吗?我面临着几乎相同的问题,不知道如何正确使用枚举来解决这个问题。提前感谢您是否确定需要向下广播(应尽可能避免)?如果您控制
Trait
Foo
,您很可能会避免它。这似乎是
Enum
s的目标场景。@goertzenator您能提供一个示例吗?我面临着几乎相同的问题,不知道如何正确使用枚举来解决这个问题。提前感谢您是否确定需要向下广播(应尽可能避免)?如果您控制
Trait
Foo
,您很可能会避免它。这似乎是
Enum
s的目标场景。@goertzenator您能提供一个示例吗?我面临着几乎相同的问题,不知道如何正确使用枚举来解决这个问题。提前谢谢
trait Trait {
    fn trait_method(&self);
    fn foo_method(&self) {} // does nothing by default
}

struct Foo;

impl Trait for Foo {
    fn trait_method(&self) {
        println!("In trait_method of Foo");
    }

    fn foo_method(&self) { // override default behavior
        println!("In foo_method");
    }
}

struct Bar;

impl Trait for Bar {
    fn trait_method(&self) {
        println!("In trait_method of Bar");
    }
}

fn main() {
    let vec: Vec<Box<Trait>> = vec![Box::new(Foo), Box::new(Bar)];

    for e in &vec {
        e.trait_method();
        e.foo_method();
    }
}
use std::any::Any;

trait Trait {
    fn as_any(&self) -> &Any;
}

struct Foo;

impl Trait for Foo {
    fn as_any(&self) -> &Any {
        self
    }
}

fn downcast<T: Trait + 'static>(this: &Trait) -> Option<&T> {
    this.as_any().downcast_ref()
}
if let Some(r) = downcast::<Foo>(trait_object_ref) {
    r.foo_method();
}