rust - 防止直接初始化类型别名
问题描述
我目前正在学习 rust 并偶然发现了一个我不知道如何解决的问题。
我想要一个类型(称为Guess
),这i32
仅限于某个数字范围(在下面的示例中介于 1 和 100 之间)。我目前的解决方案是使用实现new
函数的类型别名来强制数字范围。仍然可以通过正常初始化创建它,而不使用Guess::new()
,因为没有像结构中那样的私有字段。
这可以防止吗?还应防止直接更改该值。
代码示例(操场):
type Guess = i32;
trait G {
fn new(val: i32) -> Guess;
}
impl G for Guess {
fn new(val: i32) -> Guess {
if val < 1 || val > 100 {
panic!("Only guesses between 1 and 100 are allowed!");
}
val
}
}
fn main() {
let guess: Guess = 23; // should not be allowed
let guess: Guess = Guess::new(42); // only this should be allowed
println!("Guess this number: {}", guess);
}
解决方案
正如其他人所说,您要做的是使用“newtype”模式,它基本上是将您的类型包装成另一个:
struct Guess(i32);
impl Guess {
fn new(val: i32) -> Self {
assert!(val >= 1 && val <= 100,
"Only guesses between 1 and 100 are allowed!");
Self(val)
}
}
fn main() {
//let guess: Guess = 23; // this is an error now
let guess: Guess = Guess::new(42); // fine
println!("Guess this number: {}", guess.0);
}
主要区别在于用户将需要使用guess.0
.
还有其他一些改进:
- 不需要一个特征来定义方法。
- 使用
Self
避免了类型名的重复。 assert!
对于if
+panic!
。
推荐阅读
- signal-processing - 软件定义无线电新手:从零基础课程和 LTE 信号处理材料开始?
- flutter - Flutter json_serializable 构建失败
- python - Python 字典列表非规范化
- ios - 我可以创建一个我的所有视图控制器都可以访问的类吗
- java - 如何用 Optionals(函数式编程)替换我的旧 Java 代码?
- php - PHP str_replace 的奇怪行为在数据数组上使用 $amp
- html - 如何将检查图标放入我的进度条
- linux - NFS 挂载点作为磁盘设备 linux
- wxpython - wxGetStockLabel(): 无效的库存项目 ID
- llvm - 当我在 llvm 中声明一个 int64 全局变量时出现问题