F# 运算符“?" [英] F# operator "?"
问题描述
我刚刚阅读了关于这个页面,而一个新的?提到了操作符,我不清楚它的用法是什么.
任何人都可以提供一个快速的解释,发布一个关于如何使用这个运算符的代码片段,并可能提到一个用例?
编辑:这真的很尴尬,我注意到 ?Don 的发行说明中不再提及运算符.知道这是为什么吗?
I just read the information on this page, and while a new ? operator is mentioned, it's quite unclear to me what would its usage be.
Could anyone please provide a quick explanation, post a code snipped of how would this operator be used and possibly mention a use case?
Edit: this is really awkward, I've noticed that the ? operator is no longer mentioned in Don's release notes. Any idea of why is that?
推荐答案
此 F# 版本中有两个新的特殊"运算符,(?) 和 (?<-).它们没有定义,但它们可用于重载,因此您可以自己定义它们.特殊的一点是他们如何处理他们的第二个操作数:他们要求它是一个有效的 F# 标识符,但将它作为字符串传递给实现运算符的函数.换句话说:
There are two new "special" operators in this F# release, (?) and (?<-). They are not defined, but they are available for overloading, so you can define them yourself. The special bit is how they treat their 2nd operand: they require it to be a valid F# identifier, but pass it to function implementing the operator as a string. In other words:
a?b
脱糖为:
(?) a "b"
和:
a?b <- c
脱糖为:
(?<-) a "b" c
这些运算符的一个非常简单的定义可能是:
A very simple definition of those operators could be:
let inline (?) (obj: 'a) (propName: string) : 'b =
let propInfo = typeof<'a>.GetProperty(propName)
propInfo.GetValue(obj, null) :?> 'b
let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
let propInfo = typeof<'a>.GetProperty(propName)
propInfo.SetValue(obj, value, null)
请注意,由于 gettor 的返回类型是通用的,因此在大多数情况下您必须在使用站点指定它,即:
Note that since the return type for the gettor is generic, you'll have to specify it at use site in most cases, i.e.:
let name = foo?Name : string
虽然你仍然可以链式调用 (?)(因为 (?) 的第一个参数也是通用的):
though you can still chain-call (?) (since first argument of (?) is also generic):
let len = foo?Name?Length : int
另一个更有趣的实现是重用VB提供的CallByName方法:
Another, more interesting, implementation is to re-use CallByName method provided by VB:
open Microsoft.VisualBasic
let inline (?) (obj: 'a) (propName: string) : 'b =
Interaction.CallByName(obj, propName, CallType.Get, null) :?> 'b //'
let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
Interaction.CallByName(obj, propName, CallType.Set, [| (value :> obj) |])
|> ignore
这样做的好处是它可以正确处理属性和字段,使用 IDispatch COM 对象等.
The advantage of that is that it will handle both properties and fields correctly, work with IDispatch COM objects, etc.
这篇关于F# 运算符“?"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!