我如何 return 来自方法的特征实例?
How do I return an instance of a trait from a method?
我正在尝试创建一个 returns Shader
特征实例的函数。这是我大大简化的代码:
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]: the trait bound `Shader + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:10:32
|
10 | fn create_shader(&self) -> Shader {
| ^^^^^^ `Shader + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Shader + 'static`
= note: the return type of a function must have a statically known size
较新版本的编译器出现此错误:
error[E0277]: the size for values of type `(dyn Shader + 'static)` cannot be known at compilation time
--> src/main.rs:9:32
|
9 | fn create_shader(&self) -> Shader {
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn Shader + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: the return type of a function must have a statically known size
这是有道理的,因为编译器不知道特征的大小,但我在任何地方都找不到修复此问题的推荐方法。
据我所知,用 &
传回引用是行不通的,因为引用会比其创建者的生命周期更长。
也许我需要使用 Box<T>
?
Rust 1.26 及更高版本
fn create_shader(&self) -> impl Shader {
let shader = MyShader;
shader
}
它确实有局限性,例如不能在特征方法中使用,并且不能在具体 return 类型是有条件的时候使用。在这些情况下,您需要使用下面的特征对象答案。
Rust 1.0 及更高版本
你需要return某种特征对象,例如&T
或Box<T>
,你是对的&T
在这种情况下是不可能的:
fn create_shader(&self) -> Box<Shader> {
let shader = MyShader;
Box::new(shader)
}
另请参阅:
- What is the correct way to return an Iterator (or any other trait)?
我认为您可以使用泛型和静态分派(我不知道这些术语是否正确,我只是看到其他人使用它们)来创建这样的东西。
这不完全是 "returning as a trait",但它让函数可以通用地使用特征。在我看来,语法有点晦涩,所以很容易错过。
我问 关于返回 Iterator
特性。它变得丑陋。
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());
}
我想这就是您要找的; a simple factory implemented in Rust:
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());
}
我正在尝试创建一个 returns Shader
特征实例的函数。这是我大大简化的代码:
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]: the trait bound `Shader + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:10:32
|
10 | fn create_shader(&self) -> Shader {
| ^^^^^^ `Shader + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Shader + 'static`
= note: the return type of a function must have a statically known size
较新版本的编译器出现此错误:
error[E0277]: the size for values of type `(dyn Shader + 'static)` cannot be known at compilation time
--> src/main.rs:9:32
|
9 | fn create_shader(&self) -> Shader {
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn Shader + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: the return type of a function must have a statically known size
这是有道理的,因为编译器不知道特征的大小,但我在任何地方都找不到修复此问题的推荐方法。
据我所知,用 &
传回引用是行不通的,因为引用会比其创建者的生命周期更长。
也许我需要使用 Box<T>
?
Rust 1.26 及更高版本
fn create_shader(&self) -> impl Shader {
let shader = MyShader;
shader
}
它确实有局限性,例如不能在特征方法中使用,并且不能在具体 return 类型是有条件的时候使用。在这些情况下,您需要使用下面的特征对象答案。
Rust 1.0 及更高版本
你需要return某种特征对象,例如&T
或Box<T>
,你是对的&T
在这种情况下是不可能的:
fn create_shader(&self) -> Box<Shader> {
let shader = MyShader;
Box::new(shader)
}
另请参阅:
- What is the correct way to return an Iterator (or any other trait)?
我认为您可以使用泛型和静态分派(我不知道这些术语是否正确,我只是看到其他人使用它们)来创建这样的东西。
这不完全是 "returning as a trait",但它让函数可以通用地使用特征。在我看来,语法有点晦涩,所以很容易错过。
我问 Iterator
特性。它变得丑陋。
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());
}
我想这就是您要找的; a simple factory implemented in Rust:
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());
}