Gleam 中的不透明类型是一种自定义类型,只有定义该类型的模块才能构造或模式匹配该类型的值。这有助于创建只能以特定方式使用的类型。
不透明类型使用opaque关键字定义。
pub opaque type PositiveInt {
PositiveInt(inner: Int)
}
这个PositiveInt类型适用于需要整数、但该整数必须大于等于零的场合。普通的 GleamInt不能这样用,因为它们也可以是负数。
定义该类型的模块可以定义一个函数来获取内部的 int 值,以及一个用于创建PositiveInt类型的函数,如果值不是正数,该函数会返回一个错误。
pub fn from_int(i: Int) -> Result(PositiveInt, String) {
case i {
_ if i < 0 -> Error("Value must be positive")
_ -> Ok(PositiveInt(i))
}
}
pub fn to_int(i: PositiveInt) -> Int {
i.inner
}
有了这个 API,其他模块无法用负值构造PositiveInt,因此任何接受PositiveInt的函数都可以确定该值是正数。
眼尖的同学可能已经注意到,上一个练习里的TreasureChest类型并不怎么安全!
如果你用过get_treasure函数,就必须提供密码,但你仍然可以解构TreasureChest类型,在不知道密码的情况下拿到宝藏。
我们用不透明类型来解决这个问题吧。
TreasureChest。TreasureChest包含两个字段:
String。TreasureChest类型必须是不透明类型。
create函数。这个函数接受两个实参:
String类型的密码。函数返回一个TreasureChest,其中包含密码和这个值。
如果密码短于 8 个字符,函数应返回一个错误,提示Password must be at least 8 characters long。
open函数。这个函数接受两个实参:
TreasureChest。String类型的密码。如果密码与TreasureChest中的密码一致,函数就应返回宝藏,否则应返回一个错误,提示Incorrect password。