F#中向Map.TryGetValue传入元组键触发编译错误的疑问
问题原因
这个现象的核心是F#的函数/方法调用语法规则导致的参数解析差异:
F#中括号默认仅用于表达式分组,不用于标识函数调用。在调用符合.NET规范的类库方法时,Method(a, b)的语法会被编译器解析为向Method传递两个独立参数a和b,而非「传递一个由a和b组成的元组作为单个参数」。
对应你遇到的三种写法,解析逻辑完全不同:
- 第一种写法先将
(x.Instrument, x.Side)赋值给key变量,此时key的类型已经是Instrument * Side元组,调用TryGetValue key时明确传入单个元组参数,完全匹配Map<Instrument * Side, PositionData>的TryGetValue方法的参数要求,因此编译正常。 - 第二种写法
TryGetValue (x.Instrument, x.Side)会被编译器解析为给TryGetValue传入两个独立参数:第一个是Instrument类型的x.Instrument,第二个是Side类型的x.Side。而TryGetValue期望的第一个参数是Instrument * Side类型的元组键,类型不匹配,因此抛出对应编译错误。 - 第三种写法
TryGetValue ((x.Instrument, x.Side))多了一层括号,内层括号会先将两个值组合为一个元组,外层括号仅作为单个参数的包裹标识,编译器会识别为传入单个元组参数,符合方法的参数要求,因此可以正常编译。
如果你不想嵌套括号,也可以用F#的反向应用运算符<|简化写法:
match brain.Positions.TryGetValue <| (x.Instrument, x.Side) with
该写法也能正常编译运行。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

