首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为带有Sorbet属性的散列定义签名?

如何为带有Sorbet属性的散列定义签名?
EN

Stack Overflow用户
提问于 2019-06-30 20:58:53
回答 1查看 2.9K关注 0票数 4

(请注意,这在sorbet.run上是不可复制的,据我所知,只能在本地复制一份Sorbet )

我本来希望可以使用类型化结构特征创建一个方法签名,其中一个参数是options哈希,但这是行不通的:

代码语言:javascript
复制
# typed: true
require 'sorbet-runtime'
extend T::Sig

class OptionsStruct < T::Struct
  prop :x, Integer, default: 1
end

sig { params(options: OptionsStruct).void }
def method(options)
  puts options.x
end

# This works
method(OptionsStruct.new({x: 2}))

# This causes the typechecker to throw.
method({x: 2})

本质上,当您键入这个文件时,它会抱怨当需要一个Struct时,会传入一个散列。我的问题是:如何为具有特定参数的散列定义有效签名?结构显然不在这里工作。虽然我还没有试过形状,但根据文档,它们是非常有限的,所以如果可能的话,我宁愿不使用它们。

关于泛型的文献提到了散列,但似乎表明只有当哈希的键和值都是相同类型时(例如,Hash<Symbol, String>要求所有键都是符号,所有值都是String),并且没有提供任何方法(据我所知)来定义带有特定键的哈希,才能使用哈希。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-30 21:11:23

实际上,您必须选择一种不同的方式(您已经提到过的三种方式):

  1. 使用T::Hash[KeyType, ValueType]。这允许您在调用将其作为param的方法时使用{}语法,但强制您对每个条目使用相同类型的键和值。
  2. 使用T::Hash[KeyType, Object]。这个值的类型比较灵活.但你泄露了信息。
  3. 使用T::Hash[KeyType, T.any(Type1, Type2, ...)。这是介于1到2之间的中间地带。
  4. 使用形状。正如文档所言,功能可能会改变,而且是实验性的。这是在不将T::Struct的使用强加给调用者的情况下建模这样的事情的最好方法:
代码语言:javascript
复制
sig { params(options: {x: Integer}).void }
def method(options)
  puts options[:x]
end
  1. 像你一样使用T::Struct。这迫使您使用MyStruct.new(prop1: x, prop2: y, ...)调用该方法。

它们都是有效的,其中4和5是给你最安全的类型。在这两者中,4是调用者中最灵活的,但5是您知道Sorbet在短期/中期内不会改变支持的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56828043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档