dor*_*asu 1 methods default traits rust
我想实现一个允许分配泛型类型的特征。到目前为止,我已经测试了以下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);
}
Run Code Online (Sandbox Code Playgroud)
我知道这段代码并不完美,我应该使用Result返回而不是展开,但请将其放在一边,因为这是一个简单的示例。u32和 的实现String完全相同,因此我想对两者使用默认实现,而不是复制和粘贴代码。我尝试过使用其中之一,但由于Self两者返回的类型不同,编译器无法确定类型大小和错误。
在这种情况下我该如何编写默认实现?
Self默认实现需要以下限制:
Self: Sized因为Self从函数返回并将被放置在调用者的堆栈中Self: FromStr因为你正在调用parse()并input期望它产生一个类型的值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);
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
此实现与默认实现类似,允许您选择哪些类型获得该实现,但它也与通用实现类似,因为它不需要您使用任何其他特征边界修改特征方法签名:
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);
}
Run Code Online (Sandbox Code Playgroud)
三种方法之间的主要区别:
Test FromStrTest实现。| 归档时间: |
|
| 查看次数: |
1307 次 |
| 最近记录: |