泛型
泛型被广泛应用于
- 函数
- 结构体
- 枚举类型
- 方法
中,具体语法见下:
函数
fn example1 <T: std::ops::Add<Output = T>> (a: T, b: T) -> T {
a + b
}
fn main() {
let a: i32 = 114514;
let b: i32 = 1919810;
println!("{} + {} = {}\n", a, b, example1::<i32>(a, b)); // Explicit
println!("{} + {} = {}\n", a, b, example1(a, b)); // Implicit
}
结构体
枚举类型
方法和关联函数
impl <T, U> example2 <T, U> {
// Method
// Mixup x of self and y of other
fn mixup <V, W> (self, other: example2<V, W>) -> example2<T, W> {
example2 {
x: self.x,
y: other.y
}
}
// Associated function, not method
fn new (a: T, b: U) -> example2 <T, U> {
example2 {
x: a,
y: b
}
}
}
fn main() {
let example4 = example2::<i32, String>::new (114514, "1919810".to_string()); // Explicit
let example4 = example2::new (114514, "1919810".to_string()); // Implicit
let example5 = example2::<i32, String>::mixup::<f32, char> (example4, example2 {x: 114.514, y: '('}); // Explicit
let example6 = exanple2::mixup (example5, example2 {x: 114.514, y: '('}); // Implicit
}
我们需要注意的:
- 外部可以约束内部:以
fn mixup <V, W> (self, other: example2<V, W>) -> example2<T, W>
为例- 实现
impl <T, U>
可以约束模板类example <T, U>
- 模板类
example <T, U>
可以约束模板方法fn mixup <V, W> (self, other: example2<V, W>) -> example2<T, W>
- 模板方法整体
fn mixup <V, W>
可以约束模板方法的 arguments 和 return value(self, other: example2<V, W>) -> example2<T, W>
- 实现
- 模板的 implementation 不需要加
::
,但是 call 的时候需要加::
- Rust 有自动类型推断的功能
Const 泛型
另外,如同 C++ 的 std::array<type, const length>
一样,我们可以让一个类型本身为整数(称为const 泛型)
fn matrix_multiplication<T: Copy + Default + std::ops::Mul<Output = T> + std::ops::Add<Output = T>, const L: usize, const M: usize, const N: usize>(
a: &[[T; M]; L],
b: &[[T; N]; M]
) -> [[T; N]; L] {
let mut result = [[T::default(); N]; L];
for i in 0..L {
for j in 0..N {
for k in 0..M {
result[i][j] = result[i][j] + a[i][k] * b[k][j];
}
}
}
result
}
fn main() {
let a: [[i32; 3]; 4] = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]];
let b: [[i32; 4]; 1] = [[1,1,1,1]];
println!("{:?}\n", matrix_multiplication(b, a));
}
Trait
Trait,说白了,就是 Haskell 的 type class。
Example
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct Post {
pub title: String, // 标题
pub author: String, // 作者
pub content: String, // 内容
}
impl Summary for Post {
fn summarize(&self) -> String {
format!("文章{}, 作者是{}", self.title, self.author)
}
}
pub struct Weibo {
pub username: String,
pub content: String
}
impl Summary for Weibo {
fn summarize(&self) -> String {
format!("{}发表了微博{}", self.username, self.content)
}
}