我有一个特征( Select * From tabl1 where Date = '04-MAR-2020' FETCH FIRST 1 ROW )
UNION ALL
( Select * From tabl1 where Date = '05-MAR-2020' FETCH FIRST 1 ROW )
,具有功能(select object_name
from user_objects
where object_type = 'TABLE'
order by object_name
fetch first 1 row only)
UNION ALL
(select object_name
from user_objects
where object_type = 'VIEW'
order by object_name
fetch first 1 row only);
。我希望每个MyGoodTrait
的实现者也实现label(&self) -> &str
和MyGoodTrait
。但是,我不一定需要Display
和FromStr
才能成为Display
的特征。我宁愿以某种方式使用FromStr
和MyGoodTrait
的默认实现,它们将在内部使用Display
中的FromStr
函数。这样,label
的每个实现者都将免费获得MyGoodTrait
和MyGoodTrait
,就像这些特征有默认实现一样。
这是一个与我想要执行的操作类似的示例,但是无法编译:
Display
是否有一种方法可以编写FromStr
和use std::str::FromStr;
pub trait MyGoodTrait {
fn new() -> Self;
fn label(&self) -> &'static str;
}
impl FromStr for dyn MyGoodTrait {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new())
}
}
pub struct A {}
impl MyGoodTrait for A {
fn new() -> Self {
A{}
}
fn label(&self) -> &'static str {
"A"
}
}
pub struct B {}
impl MyGoodTrait for B {
fn new() -> Self {
B{}
}
fn label(&self) -> &'static str {
"B"
}
}
// In this hypothetical, A and B now both have `fmt` and `from_str` functions
的默认实现,这样我就不必为实现Display
的每个结构重复代码?
注意:我的实际用例是我有一个特征,该特征具有FromStr
和MyGoodTrait
作为超特征。我特质的实现者将用作映射中的键,并且我将序列化为JSON,因此我需要将实现者序列化为String。因此,这可能是XY Problem
答案 0 :(得分:2)
TL; DR:您不能。
您无法为FromStr
实现dyn SomeTrait
,因为它有一个返回Result<Self, _>
的方法,因此您只能为在编译时知道大小的类型实现它。特质对象不是这种情况。
您真正想要的是
impl<T: MyGoodTrait> FromStr for T
但是现在您可能违反了孤立规则。如编译器所解释:
只有在至少一种实施本地特征的类型是本地的情况下,才能实现该特征。 对于类型参数,只能实现当前包装箱中定义的特征。
但是如果FromStr
是本地特征,您可以这样做:
/// Copy of `std::str::FromStr`
trait Foo: Sized {
type Err;
fn from_str(s: &str) -> Result<Self, Self::Err>;
}
impl<T: MyGoodTrait> Foo for T {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new())
}
}
或者您可以将其实现为任何特定的本地类型:
impl FromStr for A {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new())
}
}