无法在 F# 签名文件 (.fsi) 中使用文字属性
Posted
技术标签:
【中文标题】无法在 F# 签名文件 (.fsi) 中使用文字属性【英文标题】:Unable to use the Literal attribute in an F# Signature file (.fsi) 【发布时间】:2018-01-11 17:23:58 【问题描述】:我无法在 F# 签名文件中定义文字。
我有一个文件,File.fs
,如下:
module Thingo =
[<Literal>]
let hello = "world"
我需要为它创建一个签名文件,所以最初尝试了这个(File.fsi
):
module Thingo =
[<Literal>]
val hello : string
这导致File.fsi
出现以下错误:A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
我试了一下:
module Thingo =
[<Literal>]
val hello : string = "world"
val hello
声明之后的行收到错误:Incomplete structured construct at or before this point in signature file. Expected incomplete structured construct at or before this point or other token.
所以它不喜欢我在签名文件中分配值(或者我不知道如何分配值,很有可能)。
文档说我确实需要以某种方式在签名中分配值:
如果使用
Literal
属性,它必须同时出现在签名和实现中,并且两者必须使用相同的文字值。
(来自https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/signatures)
我还自动生成了一个签名文件(使用 --sig
构建参数),它吐出:
module EventSchema = begin
[<LiteralAttribute ()>]
val id : string
end
我试过这个确切的语法,但也没有用。
感谢阅读!任何建议将不胜感激。
【问题讨论】:
如果您删除模块名称后的=
,您的第三个sn-p(包含字符串值的那个)将起作用。但是如果你添加其他行它就会失败,它似乎只有当文字是你声明的最后一件事时才有效,这似乎是一个错误。
假设这是一个错误,自从一年前提出这个问题以来,这个问题是否已在 F# 的某些后续版本中得到修复,还是计划在即将发布的版本中修复?我遇到了同样的问题。
遗憾的是,我从来没有解决这个问题,但我也没有继续尝试修复它。我不知道它是否会在未来的版本中得到修复。
现已修复,将成为 F# 下一版本的一部分,请参阅 github.com/dotnet/fsharp/issues/7897
【参考方案1】:
正确的答案应该是:这是一个错误。此处报道:https://github.com/dotnet/fsharp/issues/7897。
请注意,作为一种解决方法,您可以关闭轻量级语法,然后它将在当前版本中工作。
还要注意,当常量值与签名文件中的值不匹配时,编译器会出错。
【讨论】:
【参考方案2】:您应该在模块之前的文件开头使用命名空间或删除“=”符号。此外,不需要类型注释。 F# 非常擅长类型推断。
module Thingo
[<Literal>]
val hello= "world"
或
namespace My.App.Modules
module Thingo =
[<Literal>]
val hello = "world"
【讨论】:
以上是关于无法在 F# 签名文件 (.fsi) 中使用文字属性的主要内容,如果未能解决你的问题,请参考以下文章