【问题标题】:In F#, is there a way to define a type-checked alias for a primitive type?在 F# 中,有没有办法为原始类型定义经过类型检查的别名?
【发布时间】:2015-02-12 22:12:56
【问题描述】:

我想定义恰好由同一类型支持的类型(例如,FirstNameLastName,它们都是 strings),但我希望对它们进行类型检查,这样我就不能错误地混搭它们:

> type FirstName = string;;
type FirstName = string

> type LastName = string;;
type LastName = string

> let n : FirstName = "John";;
val n : FirstName = "John"

//I wish this were caught:
> let l : LastName = n;;
val l : LastName = "John"

有没有办法在 F# 中做到这一点,而不是定义记录类型或类似的东西?

【问题讨论】:

    标签: f#


    【解决方案1】:

    您可以使用单例区分联合:

    type FirstName =
        | FirstName of string
    
    type LastName =
        | LastName of string
    
    let n = FirstName "John"
    let l: LastName = n // error
    

    有关如何使用这些功能的更多信息,请参阅博文here

    【讨论】:

      【解决方案2】:

      我相信度量单位可以用于字符串,所以你应该能够做到这一点

      [<Measure>]
      type FirstName
      
      [<Measure>]
      type LastName
      
      let n = "John"<Firstname>
      let l:string<LastName> = n
      

      这将引发错误。 Here is the MSDN Documentation of Units of Measure

      【讨论】:

      • 理论上,这可能是个好主意。三年前,我向a related question 询问了如何管理这些计量单位,但这个问题仍然没有得到有效回答。
      • 关于计量单位的事情是它们是 F# 中的编译器功能,它们从已编译的程序集中被剥离。上面的代码在编译时会抛出错误,但在程序集中 n 和 l 只是字符串。因此,任何 .Net 程序集都可以将它们作为字符串访问,
      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 2022-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多