我想通知“此方法将返回实施Struct
和Trait
”的装箱Sized
。
简单的解决方案只是将Struct
放入Box
但我不能,因为Struct
具有如此大的通用参数,我无法手动编写。
// I can't edit these trait and struct.
trait Trait {}
struct Struct();
impl Trait for Struct {}
// This is my code.
fn func() -> Box<Trait> {
Box::new(Struct{})
}
// This is not my code.
fn need_sized<T: Trait + Sized>(item: T) {
println!("ok");
}
fn main() {
// This can not be compiled!
need_sized(func());
}
我可以修改func
功能,但我不能编辑其他功能。
如何指定Trait实现大小? 它有点像下面的东西吗?
fn func() -> Box<Trait + Sized>
答案 0 :(得分:1)
我认为您需要更改func
或need_sized
才能生效。实际上,func
会返回未归类的trait object,而need_sized
需要具体类型(更重要的是,它需要对其参数item
的完全所有权,而不仅仅是参考)。
方法1:如果您控制并可以更改func()
,则可以将其更改为返回Box<Struct>
而不是Box<Trait>
:
fn func() -> Box<Struct> {
Box::new(Struct{})
}
fn main() {
let s1 = func(); // Box<Struct>, needs dereferencing with *
// to become a Struct
need_sized(*s1); // this now works
}
方法2:如果您不控制func()
但是控制need_sized
和Trait
,您可以将Box向下转换回结构,如下所示:https://stackoverflow.com/a/33687996/497364
use std::any::Any; // needed for downcast
trait Trait {
fn as_any(&self) -> &Any;
}
struct Struct{}
impl Trait for Struct {
fn as_any(&self) -> &Any {
self
}
}
fn func() -> Box<Trait> {
Box::new(Struct{})
}
// changed to accept a &T
fn need_sized<T: Trait + Sized>(_item: &T) {
println!("ok");
}
fn main() {
let s2 = func();
if let Some(st) = s2.as_any().downcast_ref::<Struct>() {
need_sized(st);
}
}
答案 1 :(得分:1)
错误信息是;
错误[E0277]:不满足特征限制
std::boxed::Box<Trait>: Trait
添加;
impl Trait for Box<Trait> {}
在第三行之后让它编译。</ p>
答案 2 :(得分:1)
根据规范,您可以绕过此方法的唯一方法是制作newtype wrapper。
// I can't edit these trait and struct.
trait Trait {}
struct Struct();
impl Trait for Struct {}
// This is my code.
struct MyStruct(Struct);
impl Trait for Box<MyStruct> { /* if there is code here delegate to inner `Struct` */}
fn func() -> Box<MyStruct> {
Box::new(MyStruct(Struct{}))
}
// This is not my code.
fn need_sized<T: Trait + Sized>(item: T) {
println!("ok");
}
fn main() {
// This can not be compiled!
need_sized(func());
}
为什么其他方法无法解决您的问题:
单变性特征
fn func<T: Trait>() -> Box<T> { ... }
您想将func
传递给need_size
。更具体地说,您希望将Box
传递给need_size
函数。
Box<Struct>
错误[E0277]:不满足特征限制
std::boxed::Box<Struct>: Trait
--> <anon>:22:5 | 22| need_sized(func()); | ^^^^^^^^^^ the trait `Trait` is not implemented for `std::boxed::Box<Struct>` |= help: the following implementations were found: <std::boxed::Box<MyStruct> as Trait> = note: required by `need_sized`
这不起作用,因为您无法控制Box
或Struct
,因为它们未在您的箱子中定义,并且会搞乱一致性规则。将来,这可以使用特殊的一致性规则来解决。