泛型结构体 Generic Structs
与 C++ 类似, 泛型 (Generics) 这种特性在 Rust 中也被广为使用, 比如标准库中的容器类, 都离开泛型这个特性.
泛型在 Rust 里有广泛的应用, 除了本节介绍的结构体的泛型, 还有 函数泛型 以及 trait 泛型等等, 后面章节陆续会有介绍.
一般的泛型写法:
#![allow(unused)] fn main() { pub struct Queue<T> { older: Vec<T>, younger: Vec<T>, } impl<T> Queue<T> { pub fn new() -> Queue<T> { Queue { older: Vec::new(), younger: Vec::new() } } pub fn push(&mut self, t: T) { self.younger.push(t); } pub fn is_empty(&self) -> bool { self.older.is_empty() && self.younger.is_empty() } } }
使用 Where
可以使用 where
来指定复杂的泛型:
use std::fmt::{Debug, Display}; fn print_info<T>(t: T) where T: Debug + Display + Clone, { println!("debug: {:?}, display: {}", t, t.clone()); } fn main() { let s = "Hello, world".to_string(); print_info(s); }
偏特化 partial specialization
除了一般的泛型写法之外, 还可以使用偏特化为某个类型单独实现一种特殊形式.
比如, 标准库里的 Box<T>
就有这样的代码:
impl<T: Default> Default for Box<T> {
/// Creates a `Box<T>`, with the `Default` value for T.
#[inline]
fn default() -> Self {
Box::new(T::default())
}
}
impl<T> Default for Box<[T]> {
#[inline]
fn default() -> Self {
let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling();
Box(ptr, Global)
}
}
impl Default for Box<str> {
#[inline]
fn default() -> Self {
// SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`.
let ptr: Unique<str> = unsafe {
let bytes: Unique<[u8]> = Unique::<[u8; 0]>::dangling();
Unique::new_unchecked(bytes.as_ptr() as *mut str)
};
Box(ptr, Global)
}
}
接下来再看另一个示例程序, 甚至可以为不同特化的类型添加特定的方法, 来扩展它:
struct GeneralVal<T>(T); impl GeneralVal<i32> { pub fn int_value(&self) -> i32 { return self.0; } } impl GeneralVal<f64> { pub fn double(&self) -> f64 { return self.0 * 2.0; } } impl<T> GeneralVal<T> { pub fn value(&self) -> &T { return &self.0; } } fn main() { let v = GeneralVal(42); println!("val: {}", v.int_value()); let f = GeneralVal(3.14); println!("double: {}", f.double()); }