【问题标题】:Ruby alternative to void return typeRuby 替代 void 返回类型
【发布时间】:2013-02-24 21:30:25
【问题描述】:

我的经验是使用基于 C 的语言(C、C++、Java、C#),其中函数的返回类型可以是 void,即不返回。但在 Ruby 中,似乎每个函数都会返回一些东西。我想知道在 Ruby 中返回什么以获取在 Java 或 C++ 中不返回任何内容的方法。我最好的猜测是 nil 或包含方法(用于链接)的对象,或者只是忽略最后发生的任何事情,但我似乎找不到任何关于此的信息。

Ruby 中 void 的替代方法是什么?

【问题讨论】:

    标签: ruby void return-type


    【解决方案1】:

    return nil
    

    在方法的最后一条语句中。

    或者干脆

    nil
    

    【讨论】:

    • 空函数(def foo; end)也隐式返回nil
    • @Zoidberg 这是真的,但有什么实际用途吗?
    • 好吧,为了保持一致,我也会从返回“void”的函数中返回 nil
    • 从 Ruby 2.1 开始,空方法不再返回 nilsource
    • @Dimid 这是不同的问题。 a=def foo;end;b=foo()。你在谈论 a 是如何:foo,但我们在谈论 b 如何是 nil
    【解决方案2】:

    如果你不想返回任何东西,是的,你可以使用 return nil 。但为什么呢?

    通过不将函数调用分配给变量,您可以幸福地忘记返回的内容。该返回值将不会存储在任何地方,并且会在垃圾回收中丢失。

    【讨论】:

    • 如果您至少不考虑方法中的最后一个表达式对您的评估结果,可能会意外泄漏有关方法实现的信息,人们可能会开始依赖它,即使您的文档另有说法。
    【解决方案3】:

    nil 与 void 不同。您可以将变量设置为 nil,但不能将其设置为 void。如果一个函数返回 nil ,它可以被分配给一个没有错误的变量,但是尝试使用一个 void 函数(在 java 或一些支持 void 函数的此类语言中),编译器会叫。我不是 ruby​​ 超级专家,但我找不到任何迹象表明支持 void 的概念。所有函数都会返回一些东西,即使它是 nil。如果这是不正确的,那么我希望对 ruby​​ 有更多了解的人可以提供一个反例。

    变量,特别是在一切都是对象的 ruby​​ 中,是一个有名称和一个存储地址的东西,该地址指向堆上某处的对象。将变量设置为 nil 意味着将其指针设置为 NilClass 的唯一实例。 (true 和 false 相似,TrueClass 和 FalseClass 有单个实例。)

    我意识到 C 有一个叫做 void 指针的东西。这是对“无效”一词的完全不同的用法。一个 void 指针实际上包含一个地址并指向某个东西。让我们暂时忽略这些;我只是提到他们来阻止徒劳的反驳。我们专注于 ruby​​ 中的 函数,它们实际上返回 nothing,据我所知,这些函数并不存在。

    【讨论】:

      【解决方案4】:

      在现代版本的 Ruby 中,RBS supports void

      如果您不能使用 RBS,您可以使用 method_missing 相当轻松地编写自己的 Void 对象。它不会阻止分配,但它确实使调试更容易。

      # frozen_string_literal: true
      
      # Responds to all messages by raising Void::Error.
      #
      # Use for methods that only produce side-effects and do not return anything.
      # The meaning is the same as in C or Java.
      #
      # ```
      # def void_method
      #   # do side-effect
      #   Void.new
      # end
      #
      # unintentional_assignment = void_method
      # # much later ..
      # unintentional_assignment.foo
      # # => Void::Error (Void from void_method.rb received: foo)
      # ```
      class Void
        class Error < RuntimeError
        end
      
        def initialize
          @instantiation_source_location = caller[1] || 'Source unknown'
        end
      
        def method_missing(method)
          raise(
            Error,
            format(
              'Void from %s received: %s',
              @instantiation_source_location,
              method
            )
          )
        end
      
        def respond_to_missing?(*)
          true
        end
      end
      

      【讨论】:

        猜你喜欢
        • 2015-06-29
        • 2015-03-24
        • 2017-02-28
        • 2016-08-16
        • 2011-04-08
        • 1970-01-01
        • 2019-01-15
        • 2016-08-09
        • 1970-01-01
        相关资源
        最近更新 更多