如图这样弄一个newtype
会报找不到这个UserId的constructor
正确应该如何使用?
type UserId Int
fn init {
let a : UserId = UserId(100)
println(a.0)
}
所以newtype得到的类型不能infer吗?
我也刚了解,不清楚
因为有可能出现Constructor同名而无法区分类型的情况,所以需要标注类型:
type UserId Int
enum Key {
UserId(Int)
}
fn init {
let a = UserId::UserId(2)
let b : UserId = UserId(2)
let c = UserId(5) // c的类型是Key还是UserId?
}
目前 constructor 是必须要知道类型才会去解析的,哪怕没有歧义也是如此。这是因为如果允许无歧义的 constructor 直接用,那上游添加新的定义可能会 break 下游代码。所以在类型检查的时候,会拒绝推断一个 constructor 的类型。你这里的 uid0
就是因此报错。
IDE 给 uid0
标上了正确的类型,但这其实是错误恢复机制猜的,实际上编译器会拒绝这段程序。原因就是上面说的,推断 constructor 的类型会让代码更容易 break。
这里的 uid1
没有报错,是因为标注了类型,类型检查知道了类型,不需要推断。
这里的 uid2
的语法是 TypeName::Constructor
,比如 Option::Some
,是一种显示指定 constructor 的类型的方式。只不过在 new type 这里,类型名字和 constructor 名字相同,所以会出现 UserId
的重复。
未来可能会针对 newtype 这个情况给个语法糖,因为 newtype 的类型名字和 constructor 名字一样,要重复两遍确实比较啰嗦