newtype 应该怎么用?

如图这样弄一个newtype
image

会报找不到这个UserId的constructor


正确应该如何使用?

type UserId Int

fn init {
let a : UserId = UserId(100)
println(a.0)
}

所以newtype得到的类型不能infer吗?

我也刚了解,不清楚 :sweat_smile:

因为有可能出现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?
}


我这个 case 里没有同名的也有类似报错?

目前 constructor 是必须要知道类型才会去解析的,哪怕没有歧义也是如此。这是因为如果允许无歧义的 constructor 直接用,那上游添加新的定义可能会 break 下游代码。所以在类型检查的时候,会拒绝推断一个 constructor 的类型。你这里的 uid0 就是因此报错。

IDE 给 uid0 标上了正确的类型,但这其实是错误恢复机制猜的,实际上编译器会拒绝这段程序。原因就是上面说的,推断 constructor 的类型会让代码更容易 break。

这里的 uid1 没有报错,是因为标注了类型,类型检查知道了类型,不需要推断。

这里的 uid2 的语法是 TypeName::Constructor,比如 Option::Some,是一种显示指定 constructor 的类型的方式。只不过在 new type 这里,类型名字和 constructor 名字相同,所以会出现 UserId 的重复。

未来可能会针对 newtype 这个情况给个语法糖,因为 newtype 的类型名字和 constructor 名字一样,要重复两遍确实比较啰嗦

3 个赞