无法在 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 [&lt;Literal&gt;] 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) 中使用文字属性的主要内容,如果未能解决你的问题,请参考以下文章

如何从 fsharp 签名文件中的抽象类继承?

f# 我如何编译然后发布一个文件 .fsx

您可以使用 .net 内核运行 F# 脚本文件 (.fsx) 吗?

如何检测文本是不是包含 [FSI]*[PDI]

F# 签名文件和对应的实现文件中的通用函数定义

无法使用客户端签名调用将图像上传到 Cloudinary - 签名无效