You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Crystal语言中创建值为任意类型的Hash?

在Crystal语言中如何表示键为String、值为任意类型的Hash?

我正在处理一个API的表示工作,该API的响应包含一个键为String类型、值可为任意类型的Hash。我查阅了Crystal的类型相关文档,但没找到对应的表示方法。

在OpenAPI规范中,这种结构被称为自由格式对象,定义方式如下:

Free-Form Objects
如果字典的值可以是任意类型(即自由格式对象),使用additionalProperties: true:
type: object
additionalProperties: true
这等价于:
type: object
additionalProperties: {}

在Go语言中,这种类型会被表示为map[string]any或map[string]interface{}。


解答

在Crystal语言中,你可以通过两种方式实现这种结构的表示:

1. Hash(String, JSON::Any)(API场景推荐)

JSON::Any是Crystal标准库专为兼容JSON任意类型设计的类型,支持字符串、数字、布尔值、数组、嵌套哈希等所有JSON允许的类型,完美匹配OpenAPI自由格式对象的需求。同时它内置了类型转换方法,方便后续处理不同类型的值。

示例代码:

# 初始化自由格式哈希
free_form = Hash(String, JSON::Any).new

# 添加不同类型的值
free_form["username"] = "john_doe"
free_form["score"] = 95
free_form["is_verified"] = true
free_form["tags"] = ["crystal", "api"]
free_form["profile"] = {"location" => "Beijing", "join_date" => "2024-01-01"}

# 访问并转换值类型
username = free_form["username"].as_s
score = free_form["score"].as_i
tags = free_form["tags"].as_a

如果直接解析API的JSON响应,可直接将结果转为该类型:

api_response = '{"status": "ok", "data": {"id": 123, "details": ["a", "b"]}}'
parsed = JSON.parse(api_response).as_h # 直接得到Hash(String, JSON::Any)

2. Hash(String, ::Any)(通用任意类型)

若不需要和JSON序列化绑定,也可以使用Crystal的顶级Any类型,它能容纳所有Crystal对象,但使用时需手动处理类型断言,灵活性稍弱:

generic_hash = Hash(String, ::Any).new
generic_hash["count"] = 42
generic_hash["text"] = "hello"

# 类型断言访问
count = generic_hash["count"].as(Int32)
text = generic_hash["text"].as(String)

内容的提问来源于stack exchange,提问作者Grokify

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:10:32