首先,您的for
循环在错误的位置投射。你想投到data
,DynamicJsonArray
不是x
。您还需要转换x
为DynamicJsonObject
.
let myList = [
for x in (data :?> DynamicJsonArray) do
let x = x :?> DynamicJsonObject
...
F# 不像 C# 那样内置对动态对象的支持,因此您不能使用标准运算符?
来获取对象的属性。
我花了大约 20 秒试图弄清楚如何使用普通 API 提取动态属性,但很无聊。
幸运的是,F# 有一个称为 Type Providers 的功能,它在某些方面类似于动态对象,但在超级类固醇上。他们会在这里完美地工作。
添加对 NuGet 包的引用FSharp.Data
并尝试使用以下代码来确定大小:
open FSharp.Data
type WorldCup = JsonProvider<"http://worldcup.sfg.io/matches">
for game in WorldCup.GetSamples() do
match (game.Status, game.HomeTeam.Record, game.AwayTeam.Record) with
| ("completed", Some(ht), Some(at)) ->
printfn "%s %d vs %s %d" ht.Country ht.Goals at.Country at.Goals
| _ -> ()
如果您只想要工作代码,那就去吧。有关更多详细信息,请继续阅读。
与链接的 C# 代码相比,需要注意的一些事项:
- 您在 JSON 对象上获得智能感知,向您显示可用的属性(不要在 C# 中获得)
- 如果您打错了属性名称,或者假设某个属性在不可用时始终可用,则您的代码将无法构建。这可以防止 C# 中可能发生的各种运行时错误。
特别要注意的是,在原始 JSON 中,game.HomeTeam
并不总是存在(即,对于尚未玩过的游戏,它不会被填充)。您的 C# 仍然可以访问game.home_team.country, game.home_team.goals
,因为您正在过滤status
. 这目前还可以,但总的来说这是有风险的,因为这可能会在运行时爆炸。
在 F# 中,JSON 类型提供程序注意到HomeTeam
并且AwayTeam
并不总是存在,因此它将它们公开为option
types。类型系统要求您考虑当这些值丢失时该怎么做。这是好事!
因此,您会看到代码检查了 3 件事:1. status = "completed"
2.HomeTeam
已定义(是Some(homeTeam)
,不是None
)3.AwayTeam
已定义。如果是这样,我们打印详细信息。如果没有,请跳过它。