Mar*_*ill 8 f# visual-studio-2012
在Visual Studio 2012中使用F#,此代码编译:
let ``foo.bar`` = 5
Run Code Online (Sandbox Code Playgroud)
但是这段代码没有:
type ``foo.bar`` = class end
Invalid namespace, module, type or union case name
Run Code Online (Sandbox Code Playgroud)
根据F#语言规范的第3.4节:
Any sequence of characters that is enclosed in double-backtick marks (````),
excluding newlines, tabs, and double-backtick pairs themselves, is treated
as an identifier.
token ident =
| ident-text
| `` [^ '\n' '\r' '\t']+ | [^ '\n' '\r' '\t'] ``
Run Code Online (Sandbox Code Playgroud)
第5节将类型定义为:
type :=
( type )
type -> type -- function type
type * ... * type -- tuple type
typar -- variable type
long-ident -- named type, such as int
long-ident<types> -- named type, such as list<int>
long-ident< > -- named type, such as IEnumerable< >
type long-ident -- named type, such as int list
type[ , ... , ] -- array type
type lazy -- lazy type
type typar-defns -- type with constraints
typar :> type -- variable type with subtype constraint
#type -- anonymous type with subtype constraint
Run Code Online (Sandbox Code Playgroud)
......第4.2节将long-ident定义为:
long-ident := ident '.' ... '.' ident
Run Code Online (Sandbox Code Playgroud)
据我所知,从规范中可以看出,类型是用long-idents命名的,而long-ident可以是idents.由于idents支持双引号引用的标点符号,因此它似乎也应该类型.
所以我误读了规范吗?或者这是编译器错误?
Tom*_*cek 13
它看起来很像规范与实际实现不同步,因此一方或另一方存在错误.
在双反引号中使用标识符时,编译器会将其视为名称,并使用您在反引号中指定的名称生成类型(或成员).它不会进行任何名称修改以确保标识符是有效的类型/成员名称.
这意味着您不能使用与编译代码中的某些标准含义冲突的标识符并不太令人惊讶.在您的示例中,它是点,但这里有一些其他示例:
type ``Foo.Bar``() = // Dot is not allowed because it represents namespace
member x.Bar = 0
type ``Foo`1``() = // Single backtick is used to compile generic types
member x.Bar = 0
type ``Foo+Bar``() = // + is used in the name of a nested type
member x.Bar = 0
Run Code Online (Sandbox Code Playgroud)
以上示例不允许作为类型名称(因为它们与某些标准含义冲突),但您可以在let-bindings中使用它们,因为对变量名称没有这样的限制:
let ``foo`1`` = 0
let ``foo.bar`` = 2
let ``foo+bar`` = 1
Run Code Online (Sandbox Code Playgroud)
这绝对应该在文档和规范中解释,但我希望这有助于澄清发生了什么.