F# 将函数中的新值绑定到已命名的名称(标识符)?
在“Expert F#3.0”一书中,有一个“lex”和“parse”多项式表达式的文本解析示例。我试图稍微理解一下(编写的代码没有解释),我遇到了如下函数:F# 将函数中的新值绑定到已命名的名称(标识符)?,f#,f#-3.0,F#,F# 3.0,在“Expert F#3.0”一书中,有一个“lex”和“parse”多项式表达式的文本解析示例。我试图稍微理解一下(编写的代码没有解释),我遇到了如下函数: let parseIndex src = match tryToken src with | Some(Hat,src) -> match tryToken src with | Some(Int num,src) -> (num,src)
let parseIndex src =
match tryToken src with
| Some(Hat,src) ->
match tryToken src with
| Some(Int num,src) -> (num,src)
| _ -> failwith "expected an int after ^"
| _ -> (1,src)
哪个使用这个函数
let tryToken (src:TokenStream) =
match src with
| head::rest -> Some(head, rest)
| _ -> None
函数parseIndex
使用参数src
,当代码多次使用tryToken
时,每次返回的src
都是其他名称,但函数仍然使用该名称
我的问题是:parseIndex
在这里使用src
到底做了什么?因为在第二个模式匹配中,它使用了src
,就好像它是tryToken
给出的一个deffirent值一样,但是看看tryToken,我发现它在模式匹配的每次使用中都应该给出相同的结果
您看到的
Hat
和Int
是Token
的联合案例,因为type TokenStream=Token list
后面的绑定会隐藏以前的绑定。您可以任意多次绑定x
:
let x = 1
let x = 2
let x = 3
...
范围的其余部分将只看到最后一个。正如Daniel所说,这称为阴影 它在很多情况下都非常有用;想象一下这个C#函数:
public void DoStuff(string s)
{
var trimmed = s.Trim();
// For the rest of this function, we should use trimmed, but s is
// sadly still in scope :(
}
隐藏可以通过隐藏原始变量来解决此问题:
let DoStuff s =
let s = s.Trim()
// Only one 's' is in scope here, and it's trimmed
所以当你使用x时,你得到x的最后一个界值?但是src没有被反弹@扎伊达贾吉:这是在比赛模式。对不起,我说的不正确(修正)。阴影是每个范围。它不是重新绑定先前的值,而是隐藏它们。离开内部作用域后,外部
src
将再次可见。您使用的是该作用域中可见的最后一个定义(因此,从模式匹配)。@ZaidAjaj在类似这种情况下,有时会使用阴影来有意隐藏只应在外部作用域中使用的以前的值。在本例中,隐藏origionalsrc
绑定会阻止它在内部作用域中使用。