![](/img/trans.png)
[英]C++: How can I use different implementation of methods with the same data class?
[英]How can I use the same default implementation for this Rust trait
我想实现一个允许分配泛型类型的特征。 到目前为止,我已经对u32
和String
类型进行了测试:
trait Test {
fn test(&self, input: &str) -> Self;
}
impl Test for String {
fn test(&self, input: &str) -> Self {
input.parse().unwrap()
}
}
impl Test for u32 {
fn test(&self, input: &str) -> Self {
input.parse().unwrap()
}
}
fn main() {
let mut var = 0u32;
let mut st = String::default();
var = var.test("12345678");
st = st.test("Text");
println!("{}, {}", var, st);
}
我知道这段代码并不完美,我应该使用Result
返回而不是展开,但请把它放在一边,因为这是一个简单的例子。 u32
和String
的实现完全相同,所以我想对两者都使用默认实现,而不是复制和粘贴代码。 我试过使用一个,但由于返回的类型Self
在两者中都不同,编译器无法确定类型大小和错误。
在这种情况下,我该如何编写默认实现?
默认实现需要以下Self
边界:
Self: Sized
,因为Self
是从 function 返回的,将被放入调用者的堆栈中Self: FromStr
因为您在input
上调用parse()
并期望它产生一个Self
类型的值<Self as FromStr>::Err: Debug
因为当你unwrap
一个潜在的错误并且程序崩溃时 Rust 希望能够打印错误消息,这需要错误类型来实现Debug
全面实施:
use std::fmt::Debug;
use std::str::FromStr;
trait Test {
fn test(&self, input: &str) -> Self
where
Self: Sized + FromStr,
<Self as FromStr>::Err: Debug,
{
input.parse().unwrap()
}
}
impl Test for String {}
impl Test for u32 {}
fn main() {
let mut var = 0u32;
let mut st = String::default();
var = var.test("12345678");
st = st.test("Text");
println!("{}, {}", var, st);
}
通用的一揽子实现也是可能的,您可以在其中自动为满足特征界限的所有类型提供Test
的实现:
use std::fmt::Debug;
use std::str::FromStr;
trait Test {
fn test(&self, input: &str) -> Self;
}
impl<T> Test for T
where
T: Sized + FromStr,
<T as FromStr>::Err: Debug,
{
fn test(&self, input: &str) -> Self {
input.parse().unwrap()
}
}
fn main() {
let mut var = 0u32;
let mut st = String::default();
var = var.test("12345678");
st = st.test("Text");
println!("{}, {}", var, st);
}
这个实现,类似于默认实现,允许你选择哪些类型得到实现,但它也类似于通用实现,因为它不需要你用任何额外的 trait 边界修改 trait 方法签名:
trait Test {
fn test(&self, input: &str) -> Self;
}
macro_rules! impl_Test_for {
($t:ty) => {
impl Test for $t {
fn test(&self, input: &str) -> Self {
input.parse().unwrap()
}
}
}
}
impl_Test_for!(u32);
impl_Test_for!(String);
fn main() {
let mut var = 0u32;
let mut st = String::default();
var = var.test("12345678");
st = st.test("Text");
println!("{}, {}", var, st);
}
三种方法之间的主要区别:
Test
的类型都必须调整大小,并具有带有可调试错误类型的FromStr
impl。Test
实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.