![](/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.