F# nameof operator not a first-class function

元气小坏坏 提交于 2021-01-27 07:52:02

问题


I'm using F# 4.7 with <LangVersion>preview</LangVersion> in my project file.

I have a type like this:

type Record = {
  Name : string
  Description : string
  FieldNotInterestedIn: int
}

I'd like to get the names of certain fields in a type-safe way, but not all of them. I know I can get all the field names using reflection.

Here's the most concise code I came up with. Can it be any more concise?

let certainFieldNames =
  let r = Unchecked.defaultof<Record>
  
  [
    nameof r.Name
    nameof r.Description
  ]

回答1:


The special function nameof is a compile time feature, and returns the static name of the identifier. As such, it cannot be used at runtime, your runtime code will not contain any references to the function, the result is always a compile time constant.

As a consequence of this, you cannot use it with piping, or as a first class function. When you try it, you'll get the error as given.

The code you wrote is about the most concise, since you seem to want to get the name of these identifiers. There's no syntactic way to do this dynamically (other than with reflection, but that's a whole different approach).

The main reason this special function/operator was added was to help with renaming operations in code, or to safely use the name of a parameter in exceptions like ArgumentNullException.

Full details are in the RFC, in particular the section "other considerations", which details your use case: https://github.com/fsharp/fslang-design/blob/master/preview/FS-1003-nameof-operator.md

In the implementation, a long discussion was held with respect to not requiring the use of Unchecked.defaultof, but we couldn't find a good way of doing that without a significant rewrite of the parser. Note that that code doesn't add runtime overhead, it's erased.



来源:https://stackoverflow.com/questions/63002244/f-nameof-operator-not-a-first-class-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!