Ruby显式方法返回类型

3

我正在学习Ruby(具有Java / Groovy背景),似乎在编写方法时,方法签名为

def method_name
    # do something
end

由于 Ruby 具有动态特性,我理解为什么不需要显式声明返回类型。但是,假设我有一个名为 get_name 的方法。作为代码的调用者,我可能不确定它返回的是字符串还是自定义名称类型。是否有一种方法可以显式声明返回类型?如果可能的话,在 Ruby 中是否真的会这样做以清楚地表明返回值是什么?

5个回答

7
更新2019年:Ruby仍未内置静态类型或类型注释,但我们现在有第三方类型检查器。有关更多详细信息,请参见此答案
Java执行静态类型检查。它确保在编译时满足所有类型要求。Ruby更加动态化,它不进行编译时检查,其类型系统通常被称为“鸭子类型”。也就是说,“如果它像鸭子一样走路并像鸭子一样嘎嘎叫,那么它一定是鸭子”。
如果方法需要一个对象来响应某些消息(具有某些方法),那么它不关心对象的实际类型,只要它符合协议即可。如果这得到了良好的测试套件的支持,那么(可以认为)这是更好的方式,因为它允许快速原型设计和减少视觉杂波。较少的视觉混乱 - 代码更表达和易理解。其优点显而易见。 :)

1
面向对象编程语言Smalltalk、Ruby、Python和Self在“强类型”意义上是相似的,它们可以在运行时防止输入错误和减少隐式类型转换,但这些语言没有使用静态类型检查:编译器不检查或执行类型约束规则。现在使用“鸭子类型”这个术语来描述该组语言使用的动态类型范例。请注意,在类型系统中争论更好的方法是很棘手的事情。 - Michael Kohl
@MichaelKohl:这就是为什么我加入了“有争议”的说法,以保护自己。 :) - Sergio Tulentsev
@MichaelKohl:感谢您提供链接,我已经重新表述了第一句话 :) - Sergio Tulentsev
1
如果一个方法期望接收一个响应特定消息的对象(具有特定方法),那么只要该对象符合协议,它就不关心对象的实际类型。 —— 协议 就是 对象的实际类型。 - Jörg W Mittag
谢谢。我从Groovy中了解了鸭子类型。这只是一个问题,是否可能让方法的用户在需要时轻松确定返回类型,而无需查看方法内部,但看起来答案是否定的。 - Jeff Storey
显示剩余3条评论

4

2019年,Stripe发布了适用于Ruby的类型检查器Sorbet。现在可以指定方法签名,例如:

  sig {returns(String)}
  def name
    "Sergio"
  end

例如,如果您在类型方面犯了错误,程序将会出现有趣的错误。

代码:

  sig {returns(Integer)}
  def name
    "Sergio"
  end

错误信息:

editor.rb:12: Returning value that does not conform to method result type https://srb.help/7005
    12 |    "Sergio"
            ^^^^^^^^
  Expected Integer
    editor.rb:11: Method name has return type Integer
    11 |  def name
          ^^^^^^^^
  Got String("Sergio") originating from:
    editor.rb:12:
    12 |    "Sergio"
            ^^^^^^^^
Errors: 1

您可以在在线平台中使用检查器进行实验。

应该是被接受的答案! - oamandawi

2

我发现RubyMine/IntelliJ提供的注释标注对此非常有帮助。例如:

# @param [String] time_zone_offset_string eg. +10:00
# @return [Array] An array containing sign, hours and minutes
def self.parse_timezone_string(time_zone_offset_string)
  ... parse the timezone string ...
  return [sign, hours, minutes]
end

这些注释似乎不是RDoc的特性——如果它们是的话,那将是非常棒的。

1
简短的回答是:这是不可能的,也永远不会成为可能。而且它永远不会被使用。
长话短说:Ruby 不操作类型,而是操作通用对象。在某个时刻,一切都只是一个 BasicObject。Ruby 使用 Duck Typeing,其核心原则是:
“如果它走起路来像鸭子,叫起来也像鸭子,解释器就会高兴地把它当作鸭子对待。”
您可以使用 Object#class(返回对象的类)和 Object#is_a?(klass) 来检查类,但社区强烈反对这样做。只需逻辑思考、阅读源代码并使用文档即可。

永远不要说永远,看看我的其他答案。 :) - Sergio Tulentsev

0
据我所知,Ruby无法定义方法返回值的类型。但是您可以使用is_a?或class等方法来检查类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接