Newtype 模式
问题
Newtype 模式在 Rust 中有哪些应用?
答案
关于 Newtype 的基础概念和孤儿规则,请参考 Newtype 模式。本文侧重其作为设计模式的应用。
核心应用
// 1. 防止参数混淆
struct UserId(u64);
struct OrderId(u64);
fn process_order(user: UserId, order: OrderId) { /* ... */ }
// process_order(OrderId(1), UserId(2)); // ❌ 编译错误!
// 2. 限制 API 暴露
struct Email(String);
impl Email {
fn new(input: &str) -> Result<Self, &'static str> {
if input.contains('@') {
Ok(Email(input.to_string()))
} else {
Err("无效邮箱")
}
}
fn as_str(&self) -> &str {
&self.0
}
}
// 3. 为外部类型实现 trait(绕过孤儿规则)
struct Wrapper(Vec<String>);
impl std::fmt::Display for Wrapper {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[{}]", self.0.join(", "))
}
}
零成本保证
Newtype 在编译后与内部类型完全一致,没有任何运行时开销:
use std::mem;
struct Meters(f64);
assert_eq!(mem::size_of::<Meters>(), mem::size_of::<f64>()); // 完全相同
常见面试问题
Q1: Newtype 和 type alias 的区别?
答案:
| 特性 | Newtype struct X(T) | type alias type X = T |
|---|---|---|
| 新类型 | ✅ 独立类型 | ❌ 仅别名 |
| 类型安全 | ✅ 不可互换 | ❌ 可互换 |
| trait 实现 | ✅ 可以 | ❌ 不行 |
| 运行时开销 | 零 | 零 |
Newtype 创造了一个全新的类型,类型别名只是已有类型的另一个名字。