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());
}