问题
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