【问题标题】:How to add arguments after splat arguments in method calls?如何在方法调用中的 splat 参数之后添加参数?
【发布时间】:2014-05-05 09:28:06
【问题描述】:

Ruby 是一门很棒的语言,有时让我感到困惑(因为我没有那么出色)。 splat 争论是造成这种混乱的原因。所以请赐教。

给定以下方法:

def doSomething(with_this, *and_that)
  # ...
end

您可以使用 选项 1 调用该方法:

doSomething("With this", "index 0", "index 1", "etc")

或使用选项 2

an_array = ["index 0", "index 1", "etc"]
doSomething("With this", *an_array)

但是如果我的方法是这样定义的呢:

def doSomething(with_this, *and_that, and_even_that)
  # ...
end

注意splat参数后有一个参数

问题 1:除了使用以下方式之外,还有其他方法可以为 and_even_that 添加参数吗?

an_array = ["index 0", "index 1", "etc"]
doSomething("With this", *an_array, "With that")

在追求成为一名优秀的 Ruby 程序员的过程中,我也想知道这些:

额外问题

最好不要在方法定义中使用多个 splat 参数吗?

在方法定义中将 splat 参数留到最后是最佳做法吗?

提前谢谢你。

【问题讨论】:

    标签: ruby arrays function methods


    【解决方案1】:

    您混淆了使用 splat 的方法 declaration 和使用 splat 的方法 call

    它们是相互独立的:

    def regular_method(arg1, arg2, arg3)
      #do something
    end
    
    def method_with_splat(arg1, *more_args)
      # do something
    end
    
    arr = [1, 2, 3]
    
    regular_method(*arr) # works!
    
    method_with_splat(4, *arr) # works! (arg1==4, more_args==[1,2,3])
    
    method_with_splat(4, 5, *arr) # also ok! (arg1==4, more_args==[5,1,2,3])
    
    method_with_splat(*arr, 4, 5, 6) # just fine! (arg1==1, more_args==[2,3,4,5,6])
    

    因此,本着同样的精神:

    def splat_in_the_middle(arg1, *more_args, last_arg)
      # do something
    end
    
    splat_in_the_middle(*arr, 4, 5, 6) # arg1==1, more_args==[2,3,4,5], last_arg==6
    

    并对此进行扩展:

    def splat_in_the_middle(arg1, *more_args, arg2, last_arg)
      # do something
    end
    
    splat_in_the_middle(*arr, 4, 5, 6) # arg1==1, more_args==[2,3,4], arg2==5, last_arg==6
    

    注意第一个参数分配给第一个参数,最后一个参数总是分配给最后一个参数,另一个成为more_args数组的元素。

    至于你的额外问题:

    1. 不能在单个方法定义中声明多个 splat。从上面的示例中可以明显看出一个简单的原因 - 参数解析器无法知道一个 splat 在哪里结束,另一个在哪里开始:

      def two_splats(arg1, *splat1, arg2, *splat2)
        # do something!
      end
      # => syntax error!
      
      two_splats(1, 2, 3, 4, 5, 6) # arg1==1, splat1==[????] arg2==?, splat2==[????]
      

      虽然没有问题调用具有多个splat的方法:

      method_with_splat(*arr, *arr) # arg1==1, more_args=[2,3,1,2,3]
      
    2. 如果有充分的理由将你的 splat 放在中间,并且论点可读且易于理解,那么没有理由将 splat 放在中间。一个非常有用的用例,例如可能是最后一个参数是一个选项哈希:

      def splat_in_the_middle(first_arg, *one_or_more_other_args, options)
      

    【讨论】:

    • 只是为了确保我明白了,在splat_in_the_middle(*arr, 4, 5, 6) # arg1==1, more_args==[2,3,4,5], last_arg==6 x 个参数 之后 splat 将与 last “匹配” x 函数调用的参数个数?
    猜你喜欢
    • 2013-10-07
    • 1970-01-01
    • 2013-06-14
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多