我的代码中有一些域类型,我用它们来区分不同类型的字符串,因此编译器可以阻止我,例如以错误的顺序传递参数:
type Foo = string
type Bar = string
let baz (foo : Foo) (bar : Bar) = printfn "%A %A" foo bar
let f : Foo = "foo"
let b : Bar = "bar"
baz f b // this should be OK
baz b f // this shouldn't compile
然而,目前这种方法的效果并不令人满意,原因有二:
- 我无法找到一种方法来指定这一点
null
不是一个有效的值,所以我不能保证Foo
实例永远不会是null
.
- 两个咒语实际上都编译(并运行) - 所以我什么也没得到:D
有没有一种方法可以定义类型别名
a) 引用/包装相同类型,但彼此不兼容,并且
b) 不允许null
值,即使基础类型允许?
别名可以自由替换,因此无法将它们用于此目的,但您可以使用单例区分联合。使用防止使用 null 和私有实现的智能构造函数(以便定义它们的模块外部的代码无法绕过智能构造函数),您基本上应该得到您想要的内容(尽管在运行时强制检查 null可悲的是,而不是编译时间):
type Foo = private Foo of string with
static member OfString(s) =
if s = null then failwith "Can't create null Foo"
else Foo s
type Bar = private Bar of string with
static member OfString(s) =
if s = null then failwith "Can't create null Bar"
else Bar s
let baz (foo : Foo) (bar : Bar) = printfn "%A %A" foo bar
let f = Foo.OfString "foo"
let b = Bar.OfString "bar"
baz f b // ok
baz b f // type error
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)