文字属性不起作用

Ale*_*erg 17 f#

读克里斯的回答后,公众的文字- F#和博客文章在http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx我不不明白为什么以下不起作用:

[<Literal>]
let one = 1

[<Literal>]
let two = 2

let trymatch x =
    match x with
    | one -> printfn "%A" one
    | two -> printfn "%A" two
    | _ -> printfn "none"


trymatch 3
Run Code Online (Sandbox Code Playgroud)

这保持打印"3",虽然我认为不应该.我在这里看不到什么?

Tom*_*cek 23

我认为文字必须是大写的.以下工作正常:

[<Literal>]
let One = 1
[<Literal>]
let Two = 2

let trymatch x =
    match x with
    | One -> printfn "%A" One
    | Two -> printfn "%A" Two
    | _ -> printfn "none"


trymatch 3
Run Code Online (Sandbox Code Playgroud)

另外,如果你想要一个很好的通用解决方案,而不使用文字,你可以定义一个参数化的活动模式,如下所示:

let (|Equals|_|) expected actual = 
  if actual = expected then Some() else None
Run Code Online (Sandbox Code Playgroud)

然后写下来

let one = 1
let two = 2

let trymatch x =
    match x with
    | Equals one -> printfn "%A" one
    | Equals two -> printfn "%A" two
    | _ -> printfn "none"
Run Code Online (Sandbox Code Playgroud)

  • 是的,确认.编译器警告我各种明显的东西,但是当你真的需要它时...... (2认同)

kvb*_*kvb 14

其他答案是正确的 - 你必须用大写字母开始你的标识符.请参阅规范(命名模式)的第7.1.2节,其中指出:

如果long-ident是不以大写字符开头的单个标识符,则它始终被解释为变量绑定模式并表示由模式绑定的变量

  • @亚历山大-我同意这种行为令人困惑-我不知道团队为什么选择他们这样做的方法。鉴于当前的行为,似乎也有一些关于小写文字或使用阴影文字的变量名匹配的其他编译器警告。 (2认同)

Str*_*ger 7

此外,如果您不想使用大写文字,可以将它们放在模块中(此处命名为Const):

module Const =
    [<Literal>]
    let one = 1
    [<Literal>]
    let two = 2

let trymatch x =
    match x with
    | Const.one -> printfn "%A" Const.one
    | Const.two -> printfn "%A" Const.two
    | _ -> printfn "none"

trymatch 3
Run Code Online (Sandbox Code Playgroud)

  • 知道这种行为背后是否存在理由? (2认同)