如何为JSON解析指定数据类型?

Kri*_*ris 7 crystal-lang

我有一个JSON响应,它是一个哈希数组:

[{"project" => {"id" => 1, "name" => "Internal"},
 {"project" => {"id" => 2, "name" => "External"}}]
Run Code Online (Sandbox Code Playgroud)

我的代码看起来像这样:

client = HTTP::Client.new(url, ssl: true)
response = client.get("/projects", ssl: true)
projects = JSON.parse(response.body) as Array
Run Code Online (Sandbox Code Playgroud)

这给了我一个数组,但似乎我需要对元素进行类型转换以实际使用它们,否则我得到undefined method '[]' for Nil (compile-time type is (Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Type) | Array(JSON::Type))).

我试过as Array(Hash)但是这给了我can't use Hash(K, V) as generic type argument yet, use a more specific type.

如何指定类型?

Jon*_*Haß 10

您必须在访问元素时强制转换这些元素:

projects = JSON.parse(json).as(Array)
project = projects.first.as(Hash)["project"].as(Hash)
id = project["id"].as(Int64)
Run Code Online (Sandbox Code Playgroud)

http://carc.in/#/r/f3f

但对于像这样的结构良好的数据,你最好使用JSON.mapping:

class ProjectContainer
  JSON.mapping({
    project: Project
  })
end

class Project
  JSON.mapping({
    id: Int64,
    name: String
  })
end

projects = Array(ProjectContainer).from_json(json)
project = projects.first.project
pp id = project.id
Run Code Online (Sandbox Code Playgroud)

http://carc.in/#/r/f3g

您可以在https://github.com/manastech/crystal/issues/982#issuecomment-121156428查看有关此问题的更详细说明.