Rust泛型默认类型设置无效,遭遇E0308类型不匹配错误
Rust泛型类型不匹配问题解决
问题代码
尝试为泛型结构体设置默认类型并实现new方法,但编译器抛出类型不匹配错误:
use serde::Serialize; // 尝试设置默认类型 struct Student<T = Option<String>> { age: i32, data: T } impl<T> Student<T> where T: Serialize { fn new(age: i32) -> Self { Student { age, data: <Option<String>>::None // 尝试设置默认类型 } } // fn new_with_data(age: i32, data: T) -> Self { // Student { // age, // data // } // } } fn main() { let stu1 = Student::new(123); //let stu2 = Student::new_with_data(123, <Option<()>>::None); }
编译错误信息
Compiling playground v0.0.1 (/playground) error[E0308]: mismatched types --> src/main.rs:13:19 | 8 | impl<T> Student<T> where T: Serialize { | - this type parameter ... 13 | data: <Option<String>>::None | ^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found enum `std::option::Option` | = note: expected type parameter `T` found enum `std::option::Option<std::string::String>` For more information about this error, try `rustc --explain E0308`. error: could not compile `playground` due to previous error
错误原因
泛型impl<T> Student<T>中的T是任意满足Serialize约束的类型,而new方法里硬编码了data为Option<String>,编译器无法保证当前的T就是Option<String>,因此出现类型不匹配。
解决方案
方案一:为默认类型单独实现new方法
直接针对默认类型Student<Option<String>>实现new,明确返回该类型的实例:
use serde::Serialize; struct Student<T = Option<String>> { age: i32, data: T } // 仅为默认类型实现new方法 impl Student<Option<String>> { fn new(age: i32) -> Self { Student { age, data: None } } } // 泛型实现带数据的构造方法 impl<T> Student<T> where T: Serialize { fn new_with_data(age: i32, data: T) -> Self { Student { age, data } } } fn main() { let stu1 = Student::new(123); // 自动推断为Student<Option<String>> let stu2 = Student::new_with_data(123, None::<()>); // 指定T为Option<()> }
方案二:利用Default trait支持更多类型
如果希望new方法能支持所有实现了Default和Serialize的类型,可以修改约束,使用T::default()生成默认值:
use serde::Serialize; struct Student<T = Option<String>> { age: i32, data: T } impl<T> Student<T> where T: Serialize + Default { fn new(age: i32) -> Self { Student { age, data: T::default() } } fn new_with_data(age: i32, data: T) -> Self { Student { age, data } } } fn main() { let stu1 = Student::new(123); // T为Option<String>,默认值None let stu2 = Student::new_with_data(123, None::<()>); let stu3 = Student::new(456); // 同样生成Student<Option<String>>实例 }
内容的提问来源于stack exchange,提问作者Anunaki
相关产品推荐
相关产品推荐

