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

Ruby 3哈希模式匹配:如何限制rest仅包含允许的键?

Ruby 3哈希模式匹配如何限制rest仅包含指定键

Ruby 3原生模式匹配没有直接提供“约束rest仅包含允许键”的语法,但可以通过几种方式实现你的需求:

简化你当前的写法

你当前的思路是可行的,但可以简化——因为哈希匹配中的**rest永远不会是nil,没有匹配到额外键时它是空哈希,所以可以去掉rest.nil?的判断:

opts = { value: 5, limit: 10 } # 匹配成功
# opts = { value: 5 } # 匹配成功
# opts = { value: 5, foo: 10 } # 匹配失败

case opts
in value:, **rest if (rest.keys - %i[limit]).empty?
  puts "valid"
else
  puts "invalid"
end

更高效的写法可以用集合的子集判断:

allowed_rest_keys = %i[limit].to_set
case opts
in value:, **rest if rest.keys.to_set.subset?(allowed_rest_keys)
  puts "valid"
else
  puts "invalid"
end

更贴合你理想的实现方式

你提到的类似Flowtype的in value:, limit?:写法,其实可以直接用Ruby模式匹配的可选键语法实现,而且效果更直接——显式列出所有允许的键(必填+可选),多余的键会直接导致匹配失败:

opts = { value: 5, limit: 10 } # 匹配成功
# opts = { value: 5 } # 匹配成功
# opts = { value: 5, foo: 10 } # 匹配失败

case opts
in value:, limit?:
  puts "valid"
else
  puts "invalid"
end

如果还要限制值的类型,直接在键后面加上类型约束即可:

case opts
in value: Integer, limit?: Integer
  puts "valid"
else
  puts "invalid"
end

这种写法无需处理rest,直接通过模式本身约束了哈希只能包含指定的键,完全符合你的需求。

需要注意的是,limit?:表示该键可选但存在时必须符合约束;如果希望键完全可以不存在(不校验存在性),也可以写成limit: Integer | nil,效果是一致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:15:04