我正在学习 ruby(具有 java/groovy 背景),看起来在编写方法时,方法签名是
def method_name
# do something
end
凭借 ruby 的动态特性,我理解为什么没有显式声明返回类型。但是,假设我有一个名为get_name
. 作为代码的调用者,我可能不确定它是返回 String 还是某些自定义 Name 类型。有没有办法显式声明返回类型?并且(如果可能的话)这是否真的在 ruby 中做过以明确返回值是什么?
2019 年更新:ruby 中仍然没有内置静态类型或类型注释,但我们现在有 3rd 方类型检查器。有关更多详细信息,请参阅此答案。
Java 执行静态类型检查。它确保在编译时满足所有类型要求。Ruby 更加动态,它不进行编译时检查,它的类型系统通常被称为“鸭子类型”。也就是说,“如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那么它一定是鸭子”。
如果一个方法需要一个响应某些消息的对象(具有某些方法),那么只要它符合协议,它就不会关心对象的实际类型。如果这有良好的测试套件支持,那么它(可以说)是一种更好的方法,因为它允许更快的原型设计并减少视觉混乱。更少的视觉混乱 - 代码更具表现力和可理解性。这样做的好处是显而易见的。:)
2019 年,Stripe 发布了他们的红宝石类型检查器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
您可以在网上游乐场玩跳棋。
简短的回答是:这是不可能的,也永远不会成为可能。它永远不会被使用。
这是一个很长的答案:Ruby 不对类型进行操作。Ruby 对通用对象进行操作。在某些时候,一切都只是一个BasicObject
. Ruby使用Duck Typeing,有核心原理
如果它像鸭子一样走路,像鸭子一样说话,解释者很乐意把它当作鸭子对待。
您可以使用Object#class
(返回对象的类) 和来检查类Object#is_a?(klass)
,但社区强烈反对这样做。只需逻辑思考,阅读源代码并使用文档即可。
我发现 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的特性——如果它们是的话,那就太好了。
据我所知,ruby 不可能定义方法返回值的类型。但是你可以使用 is_a 之类的方法吗?或类来检查类型。