JsonProvider“这不是常量表达式或有效的自定义属性值”

10
Sorry, I can only understand and respond in English. Please let me know how I can assist you in English.
#if INTERACTIVE
#r "bin\Debug\FSharp.Data.dll"

#endif

open System
open FSharp.Data
open FSharp.Data.Json

let testJson = """{ "workingDir":"hello", "exportDir":"hi there", "items":[{ "source":"", "dest":"", "args": {"name":"that"} }] }"""

//here is where i get the error
let Schema = JsonProvider<testJson>

最后一行始终给我报错“这不是常量表达式或有效的自定义属性值”——这是什么意思?我该怎么做才能读取这个JSON呢?

2个回答

16

这个字符串必须被标记为常量。为此,请使用[<Literal>]属性。另外,类型提供程序创建的是类型而不是值,因此您需要使用type而不是let

open FSharp.Data

[<Literal>]
let testJson = """{ "workingDir":"hello", "exportDir":"hi there", "items":[{ "source":"", "dest":"", "args": {"name":"that"} }] }"""

type Schema = JsonProvider<testJson>

谢谢提供这个信息。我很好奇是否有人能够详细解释为什么必须将已经是不可变的值标记为常量。这里到底发生了什么?编辑:算了,我明白了。显然,这必须在“编译”时全部解决,而不是在运行时。 - jackmott
@jackmott 但为什么这不是默认设置呢? - knocte
@knocte的简短回答是,虽然不可变值无法更改,但它在程序运行之前并非一定已经确定。例如,不可变字符串可以在用户输入某些数据时设置。理论上,编译器可能在某些情况下能够推断出特定的不可变字符串是文字并使其成为常量,但语言很少尝试这样做,可能是因为它具有非微不足道的复杂性和编译时间成本。 - jackmott

0

JsonProvider 可以被视为一个参数化的 JSON 解析器(加上解析器生成的数据类型),在编译时进行专门化。

您提供给它的参数(字符串或指向 JSON 文件的路径)定义了 JSON 数据的结构 - 如果您愿意,可以称之为模式。这使得提供程序能够创建一个类型,该类型将具有您的 JSON 数据应具有的所有属性,静态地,并且这些属性的集合(以及它们各自的类型)是使用您提供给提供程序的 JSON 示例定义的(实际上是从中推断出来的)。

因此,在文档的示例中展示了使用 JsonProvider 的正确方法:

// generate the type with a static Parse method with help of the type provider
type Simple = JsonProvider<""" { "name":"John", "age":94 } """>
// call the Parse method to parse a string and create an instance of your data
let simple = Simple.Parse(""" { "name":"Tomas", "age":4 } """)
simple.Age
simple.Name

这个例子是从这里获取的。


是的,除了你可以使用变量,只需要将其标记为常量。 - svick
1
@svick,是的,有Literal属性,允许创建所谓的命名字面值。但正如您所说,它使“变量”成为“常量”,这有点矛盾,您同意吗? :) - MisterMetaphor
是的,但我不知道一个好术语来描述变量和常量。 - svick
@McMuttons 这不一样。例如,4是一个值,但age是一个变量(或者它可以是一个常量)。age包含一个值,但它本身不是一个值。 - svick
@svick 我想这取决于你如何命名事物。对我来说,任何返回固定结果的东西都是一个值,无论它是字面值、命名值(比如一个名为age的常量)还是一个带有固定结果的函数。而变量则是可以改变的东西,比如可变对象。我发现这种区分方式至少在函数式语言中是有意义的。即使在命令式语言中,也许取决于编码风格。 - McMuttons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接