F# 运算符“?" [英] F# operator "?"

查看:28
本文介绍了F# 运算符“?"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读了关于这个页面,而一个新的?提到了操作符,我不清楚它的用法是什么.
任何人都可以提供一个快速的解释,发布一个关于如何使用这个运算符的代码片段,并可能提到一个用例?
编辑:这真的很尴尬,我注意到 ?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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆