Crystal 处理 json 已知格式但动态密钥的文件
Crystal handle json file of known format but dynamic keys
所以我有一个 JSON 格式有点已知的文件 { String => JSON::Type, ... }
。所以它基本上是Hash(String, JSON::Type)
类型的。但是当我尝试像这样从文件读取到内存时:JSON.parse(File.read(@cache_file)).as(Hash(String, JSON::Type))
我总是得到一个例外:can't cast JSON::Any to Hash(String, JSON::Type)
我不确定如果我不能投射数据我应该如何处理它。
我基本上想做的是:
- 在字符串键下保存 JSON::Type 数据
- 将 JSON::Type 数据替换为字符串键下的其他 JSON::Type 数据
当然还有读取/写入文件...
这是我到目前为止的全部内容:
class Cache
def initialize(@cache_file = "/tmp/cache_file.tmp")
end
def cache(cache_key : (String | Symbol))
mutable_cache_data = data
value = mutable_cache_data[cache_key.to_s] ||= yield.as(JSON::Type)
File.write @cache_file, mutable_cache_data
value
end
def clear
File.delete @cache_file
end
def data
unless File.exists? @cache_file
File.write @cache_file, {} of String => JSON::Type
end
JSON.parse(File.read(@cache_file)).as(Hash(String, JSON::Type))
end
end
puts Cache.new.cache(:something) { 10 } # => 10
puts Cache.new.cache(:something) { 'a' } # => 10
TL;DR 我想将一个 JSON 文件读入一个 Hash(String => i_dont_care) 中,替换给定键名下的一个值并将其再次序列化到文件中。我该怎么做?
JSON.parse
returns 一个 JSON::Any,不是哈希,所以你不能转换它。但是,您可以访问基础原始值作为 JSON.parse(file).raw
并将其转换为散列。
那么你的代码基本上可以工作了(我已经修复了一些错误):https://carc.in/#/r/28c1
您可以使用Hash(String, JSON::Type).from_json(File.read(@cache_file))
。希望您也可以将 JSON::Type
的类型限制为更合理的类型。与使用 Hash
、Array
和使用 JSON.mapping
.
的自定义类型简单地表示您的模式相比,JSON::Any
和 JSON.parse_raw
是最后的手段
所以我有一个 JSON 格式有点已知的文件 { String => JSON::Type, ... }
。所以它基本上是Hash(String, JSON::Type)
类型的。但是当我尝试像这样从文件读取到内存时:JSON.parse(File.read(@cache_file)).as(Hash(String, JSON::Type))
我总是得到一个例外:can't cast JSON::Any to Hash(String, JSON::Type)
我不确定如果我不能投射数据我应该如何处理它。
我基本上想做的是:
- 在字符串键下保存 JSON::Type 数据
- 将 JSON::Type 数据替换为字符串键下的其他 JSON::Type 数据
当然还有读取/写入文件...
这是我到目前为止的全部内容:
class Cache
def initialize(@cache_file = "/tmp/cache_file.tmp")
end
def cache(cache_key : (String | Symbol))
mutable_cache_data = data
value = mutable_cache_data[cache_key.to_s] ||= yield.as(JSON::Type)
File.write @cache_file, mutable_cache_data
value
end
def clear
File.delete @cache_file
end
def data
unless File.exists? @cache_file
File.write @cache_file, {} of String => JSON::Type
end
JSON.parse(File.read(@cache_file)).as(Hash(String, JSON::Type))
end
end
puts Cache.new.cache(:something) { 10 } # => 10
puts Cache.new.cache(:something) { 'a' } # => 10
TL;DR 我想将一个 JSON 文件读入一个 Hash(String => i_dont_care) 中,替换给定键名下的一个值并将其再次序列化到文件中。我该怎么做?
JSON.parse
returns 一个 JSON::Any,不是哈希,所以你不能转换它。但是,您可以访问基础原始值作为 JSON.parse(file).raw
并将其转换为散列。
那么你的代码基本上可以工作了(我已经修复了一些错误):https://carc.in/#/r/28c1
您可以使用Hash(String, JSON::Type).from_json(File.read(@cache_file))
。希望您也可以将 JSON::Type
的类型限制为更合理的类型。与使用 Hash
、Array
和使用 JSON.mapping
.
JSON::Any
和 JSON.parse_raw
是最后的手段