在 Rust 中,你可以为泛型类型参数指定默认类型参数,这样在调用函数或结构体时,如果没有指定具体的类型参数,就会使用默认的类型参数。这提供了一种灵活的方式来使用泛型代码,同时保持了代码的简洁性和可读性。在使用过程中不用考虑泛型带来传入具体参数的问题。
基本语法
默认类型参数的语法是在泛型类型参数后面加上 = 和一个默认值:
在trait中指定默认类型参数
trait Add<Rhs = Self>{ type Output; #[must_use] fn add(self, rhs: RHS) -> Self::Output; }
这里Add<RHS = Self>是默认泛型类型参数,表示如果不显示指定泛型类型,就默认泛型类型为Self。当使用泛型类型参数时,可以为泛型指定一个默认的具体类型。如果默认类型就足够的话,这消除了为具体类型实现 trait 的需要。为泛型类型指定默认类型的语法是在声明泛型类型时使用 <PlaceholderType=ConcreteType>。
在结构体中指定默认类型参数
struct Stack<T = i32> { items: Vec<T>, }
用法示例
trait的默认类型参数
pub trait Watch<Inner=String> { type Item; fn inner(&self) -> Option<Self::Item>; fn info(&self) -> Inner; } struct A { data: i32, } impl Watch<i32> for A { type Item = i32; fn inner(&self) -> Option<Self::Item> { Some(self.data) } fn info(&self) -> i32 { println!("A inner is {}", self.data); self.data } } struct B { data: String, } impl Watch for B { type Item = String; fn inner(&self) -> Option<Self::Item> { Some(self.data.clone()) } fn info(&self) -> String { println!("B inner is {}", self.data); self.data.clone() } } fn call_trait_default_param_type(){ let a = A{data: 10}; let b = B{data: String::from("B")}; assert_eq!(10, a.info()); assert_eq!(Some(String::from("B")), b.inner()); }
我们在上述的例子中我们创建了一个
Watch
的trait
里面的默认类型为String
,trait中定义了一个关联变量Item
和两个函数分别是inner
和info
。
再创建一个结构体B
,里面包含一个字段类型是String
,为结构体B实现trait Watch
并把关联类型设置为String
,分别实现trait中定义的两个函数。在main函数中创建两个结构体实例,分别调用实现了trait的两个方法。结构体中默认参数类型
struct Stack<T = i32> { items: Vec<T>, } impl<T> Stack<T> { fn new() -> Self { Stack { items: Vec::new() } } } impl Stack<i32> { fn new_with_int() -> Self { Stack { items: vec![1, 2, 3] } } } fn main() { let stack_default: Stack<i32> = Stack::new(); // 使用默认类型参数 i32 let int_stack = Stack::new_with_int(); // 明确指定 i32 类型参数 }
上述代码中我们创建一个泛型结构体
Stack
,其中该泛型结构体的默认参数类型是i32
类型。接着我们实现不指定泛型参数类型的函数new
和指定默认类型的new_with_int
函数。然后在main函数中调用上述方法。使用场景
- 提供默认行为:当你想要提供一个通用的函数或结构体时,可以为不经常变化的参数提供默认值。
- 简化函数调用:在大多数情况下,如果有一个常用的类型,你可以让函数调用者不必每次都指定类型参数。
保持向后兼容:当你更新库或 API 时,添加新的泛型参数并为它们提供默认值可以避免破坏现有代码。
注意事项
默认参数类型智能在结构体,枚举,trait以及type中使用,不能在函数中使用默认类型参数。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。