【问题标题】:ruby class#initialize manifold argumentsruby 类#初始化流形参数
【发布时间】:2014-10-22 11:13:41
【问题描述】:

我不明白。 这个有效:

class Foo
  def initialize(*args)
    @variables = *args unless args[0].eql?(nil)
  end
end

这个没有:

class Foo
  def initialize(*args)
    args[0].eql?(nil) ? @multiples = [3,5] : @multiples = *args
  end
end

但是这个也可以:

class Foo
  def initialize(*args)
    args[0].eql?(nil) ? @multiples = [3,5] : @multiples = args
  end
end

我的问题是关于第二种形式和第三种形式之间的“args”和“*args”。 这是为什么呢?

【问题讨论】:

    标签: ruby ruby-2.1


    【解决方案1】:

    如您所知,splat 运算符(星号 *)在方法定义中使用时,将捕获无限数量的参数并将它们转换为数组。但是,当在 METHOD 主体中使用时,其目的是不同的。在进行分配时将 splat * 放在方法主体中是没有意义的,因为

    a) 你会得到和不放一样的结果。

    class Foo
      def initialize(*args)
        @a = args
        @b = *args
        p @a == @b
      end
    end
    
    Foo.new(1,2,3) #=> prints 'true'
    

    b) 你会得到奇怪的错误,就像你的第二个例子一样,这可能会产生错误,因为 Ruby 混淆了运算符的优先级。但是,如果您在整个表达式周围加上括号,它将起作用:

    class Foo
      def initialize(*args)
        args[0].eql?(nil) ? @multiples = [3,5] : (@multiples = *args)
      end
    end
    

    总而言之,在将 splat 分配给变量时,不要使用 * 。

    顺便说一句,有点跑题了,你可以只使用do arg[0].nil? 而不是args[0].eql?(nil) 另外,你可以执行以下操作,而不是分配两次@multiples:

    @multiples = args[0].nil? ? [3,5] : args
    

    【讨论】:

    • 实际上与 splat 运算符存在“冲突”:在方法定义中用于捕获多个参数,而在主体方法中用于乘法?对吗?
    • 好吧,它在方法主体中用于多种用途,请参阅endofline.wordpress.com/2011/01/21/the-strange-ruby-splat,我假设这个错误是由于一些“碰撞”是的。在方法体中正确使用时,splat 会非常有用,请参阅本文中的一些示例。
    • 和零的好提示。也是一个对象。 Ruby 中的一切都是对象。一个菜鸟很难掌握的概念。再次感谢 ;)
    猜你喜欢
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    相关资源
    最近更新 更多