Rust 如何从方法返回trait的实例?

Rust 如何从方法返回trait的实例?,rust,traits,Rust,Traits,我试图创建一个函数,返回着色器的一个实例。以下是我的简化代码: trait Shader {} struct MyShader; impl Shader for MyShader {} struct GraphicsContext; impl GraphicsContext { fn create_shader(&self) -> Shader { let shader = MyShader; shader } } fn ma

我试图创建一个函数,返回
着色器的一个实例。以下是我的简化代码:

trait Shader {}

struct MyShader;
impl Shader for MyShader {}

struct GraphicsContext;

impl GraphicsContext {
    fn create_shader(&self) -> Shader {
        let shader = MyShader;
        shader
    }
}

fn main() {}
但是,我收到以下错误:

error[E0277]:特性绑定的'Shader+'static:std::marker::Sized'不满足
-->src/main.rs:10:32
|
10 | fn创建_着色器(&self)->着色器{
|^^^`Shader+'static`在编译时没有已知的常量大小
|
=帮助:特性'std::marker::Sized'未为'Shader+'静态实现`
=注意:函数的返回类型必须具有静态已知的大小
较新版本的编译器存在以下错误:

error[E0277]:编译时无法知道类型为`(dyn Shader+'static)`的值的大小
-->src/main.rs:9:32
|
9 | fn创建_着色器(&self)->着色器{
|^^^^^在编译时没有已知的大小
|
=help:trait`std::marker::Sized`未为`(dyn Shader+'静态)实现`
=注意:要了解更多信息,请访问
=注意:函数的返回类型必须具有静态已知的大小
这是有道理的,因为编译器不知道trait的大小,但是我找不到推荐的方法来修复它。 就我所知,用
&
传回引用不会起作用,因为引用将超过其创建者的生命周期

也许我需要使用
Box

Rust 1.26及更高版本 :

它确实有局限性,例如不能在trait方法中使用,并且在具体返回类型为条件时不能使用。在这些情况下,您需要使用下面的trait对象答案

锈1.0及以上 您需要返回某种类型的trait对象,例如
&T
Box
,您是对的,在这种情况下
&T
是不可能的:

fn create_shader(&self) -> Box<Shader> {
    let shader = MyShader;
    Box::new(shader)
}
fn创建着色器(&self)->框{
让shader=MyShader;
框::新建(着色器)
}
另见:


我认为您可以使用泛型和静态分派(我不知道这些术语是否正确,我只是看到其他人使用它们)来创建这样的东西

这并不完全是“作为特征返回”,而是让函数一般地使用特征。在我看来,语法有点模糊,所以很容易忽略

我问过如何返回
迭代器
特征。它变得很难看

:

struct神话{
名称:String,
}
性状我的性状{
fn get_name(&self)->字符串;
}
impl MyTrait用于神话{
fn get_name(&self)->字符串{
self.name.clone()
}
}
fn作为特征(t:t)->t{
T
}
fn main(){
让t=神话{
名称:“James”。to_string(),
};
让新的t=as_特质(t);
println!(“你好,世界!{}”,new_t.get_name());
}

我想这就是您要搜索的内容;:

pub-trait命令{
fn执行(&self)->字符串;
}
结构AddCmd;
结构DeleteCmd;
AddCmd的impl命令{
fn执行(&self)->字符串{
将“.It”添加到()
}
}
DeleteCmd的impl命令{
fn执行(&self)->字符串{
“It delete.”改为()
}
}

fn command(s:&str)->optione即使不添加as_trait()函数,也可以调用
get_name
方法。最好指出,
impl trait
实际上创建了一个使用静态多态性的泛型函数。因此,如果目标是具有动态多态性(也就是在运行时发生行为更改),退回a(盒装)更好trait对象,也称为
Box
。为什么不能从trait方法返回
impl Shader
?我不需要条件返回类型,因为实现trait的每个结构只会返回一个特定的变量。但我仍然被迫使用
Box
方法,因为我需要使用trait方法。简而言之,因为该语言不支持它。该语言还不支持它,因为这需要更多的类型系统机器,我们还没有完成。@SteveKlabnik您知道该语言何时可以支持从trait方法返回impl着色器吗?还没有时间线。我们首先需要一个名为“GATs”的功能。
fn create_shader(&self) -> Box<Shader> {
    let shader = MyShader;
    Box::new(shader)
}
struct MyThing {
    name: String,
}

trait MyTrait {
    fn get_name(&self) -> String;
}

impl MyTrait for MyThing {
    fn get_name(&self) -> String {
        self.name.clone()
    }
}

fn as_trait<T: MyTrait>(t: T) -> T {
    t
}

fn main() {
    let t = MyThing {
        name: "James".to_string(),
    };
    let new_t = as_trait(t);

    println!("Hello, world! {}", new_t.get_name());
}
pub trait Command {
    fn execute(&self) -> String;
}

struct AddCmd;
struct DeleteCmd;

impl Command for AddCmd {
    fn execute(&self) -> String {
        "It add".into()
    }
}

impl Command for DeleteCmd {
    fn execute(&self) -> String {
        "It delete".into()
    }
}

fn command(s: &str) -> Option<Box<Command + 'static>> {
    match s {
        "add" => Some(Box::new(AddCmd)),
        "delete" => Some(Box::new(DeleteCmd)),
        _ => None,
    }
}

fn main() {
    let a = command("add").unwrap();
    let d = command("delete").unwrap();
    println!("{}", a.execute());
    println!("{}", d.execute());
}