通用哈希作为参数?



我正在尝试实现一个接受通用有效负载然后将其转换为 JSON 的类:

require "json"
class Response
alias Payload = Hash(Symbol | String, String | Bool | Int32 | Int64 | Float32 | Float64 | Nil)
@payload : Payload
def initialize(@payload, @method : String = "sendMessage")
end
def to_json
@payload.merge({"method" => @method}).to_json
end
end
Response.new({
"chat_id" => update.message.not_nil!.chat.id,
"text"    => "Crystal is awesome but complicated",
})

但是我得到instance variable '@payload' of Response must be Hash(String | Symbol, Bool | Float32 | Float64 | Int32 | Int64 | String | Nil), not Hash(String, Int64 | String)编译器错误。我怎样才能克服这个问题?水晶支持通用哈希吗?为什么即使类型重叠也无法转换?

Response是分片的一部分,所以我不知道哪些哈希值会作为参数传递,但Payload必须足够了。

您的有效负载哈希类型为Hash(String, Int32 | String)

typeof({
"chat_id" => update.message.not_nil!.chat.id,
"text"    => "Crystal is awesome but complicated",
}) # => Hash(String, Int32 | String)

但是构造函数期望Hash(Symbol | String, String | Bool | Int32 | Int64 | Float32 | Float64 | Nil). 这些是不同的类型,不能神奇地施放。您需要确保有效负载具有正确的类型。

执行此操作的一种方法是显式声明哈希文本的类型:

Payload{
"chat_id" => update.message.not_nil!.chat.id,
"text"    => "Crystal is awesome but complicated",
}

这当然不是很好,但根据您的用例,它可能就足够了。

如果你想要一个允许接收任何类型的哈希的通用接口,你需要将其转换为Payload类型。这意味着将数据复制到该类型的新哈希中:

def self.new(hash, method : String = "sendMessage")
payload = Payload.new
hash.each do |key, value|
payload[key] = value
end
new(payload, method)
end

对于一个实际的例子,我在 Crinja 中使用这种方法将许多不同类型的变体转换为匹配的变体。

相关内容

  • 没有找到相关文章

最新更新