天道酬勤,学无止境

Why can I have required parameters after a splat in Ruby but not optional ones? [duplicate]

This is possible in Ruby:

class SomeClass
  def initialize(a, *b, c)
  end
end

but this is not:

class SomeClass
  def initialize(a, *b, c='anything here')
  end
end

Why?

Edit: This question does NOT have an answer. In the answer linked, the first answer is:

The splat means "use up all of the remaining arguments" but then you provide an optional argument, so how could the interpreter know if the last argument is part of the "numbers" splat or the optional "options"?

Which is NOT a valid answer because according to this logic, Ruby would also not allow mandatory parameters after a splat.

标签

评论

Ruby's argument binding semantics are already pretty complex. Consider this method:

def foo(m1, m2, o1=:o1, o2=:o2, *splat, m3, m4, 
          ok1: :ok1, mk1:, mk2:, ok2: :ok2, **ksplat, &blk)
  local_variables.map {|var| [var, eval(var.to_s)] }.to_h
end

method(:foo).arity
# => -5

method(:foo).parameters
# => [[:req, :m1], [:req, :m2], [:opt, :o1], [:opt, :o2], [:rest, :splat], 
#     [:req, :m3], [:req, :m4], [:keyreq, :mk1], [:keyreq, :mk2], 
#     [:key, :ok1], [:key, :ok2], [:keyrest, :ksplat], [:block, :blk]]

Can you tell at first glance what the result of the following invocations will be?

foo(1, 2, 3, 4)

foo(1, 2, 3, mk1: 4, mk2: 5)

foo(1, 2, 3, 4, mk1: 5, mk2: 6)

foo(1, 2, 3, 4, 5, mk1: 6, mk2: 7)

foo(1, 2, 3, 4, 5, 6, mk1: 7, mk2: 8)

foo(1, 2, 3, 4, 5, 6, 7, mk1: 8, mk2: 9)

foo(1, 2, 3, 4, 5, 6, 7, 8, mk1: 9, mk2: 10)

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11)

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12)

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13)

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13, k4: 14)

foo(1, 2, 3, 4, 5, 6, 7, 8, 
      ok1: 9, ok2: 10, mk1: 11, mk2: 12, k3: 13, k4: 14) do 15 end

Now, imagine adding optional parameters with default arguments after the splat parameter to that list. It's not impossible to find sane semantics for that, but it may lead to some non-obvious results.

Can you come up with simple, sane, backwards-compatible, and non-surprising semantics?

BTW: here's the cheatsheet for the method at the top:

foo(1, 2, 3, 4)
# ArgumentError: missing keywords: mk1, mk2

foo(1, 2, 3, mk1: 4, mk2: 5)
# ArgumentError: wrong number of arguments (3 for 4+)

foo(1, 2, 3, 4, mk1: 5, mk2: 6)
# => { m1: 1, m2: 2, o1: :o1, o2: :o2, splat: [], m3: 3, m4: 4, 
#      ok1: :ok1, mk1: 5, mk2: 6, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, mk1: 6, mk2: 7)
# => { m1: 1, m2: 2, o1: 3, o2: :o2, splat: [], m3: 4, m4: 5, 
#      ok1: :ok1, mk1: 6, mk2: 7, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, mk1: 7, mk2: 8)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [], m3: 5, m4: 6, 
#      ok1: :ok1, mk1: 7, mk2: 8, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, mk1: 8, mk2: 9)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5], m3: 6, m4: 7, 
#      ok1: :ok1, mk1: 8, mk2: 9, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, mk1: 9, mk2: 10)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: :ok1, mk1: 9, mk2: 10, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: 9, mk1: 10, mk2: 11, ok2: :ok2, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13, k4: 14)
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, 
#      blk: nil }

foo(1, 2, 3, 4, 5, 6, 7, 8, 
      ok1: 9, ok2: 10, mk1: 11, mk2: 12, k3: 13, k4: 14) do 15 end
# => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
#      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, 
#      blk: #<Proc:0xdeadbeefc00l42@(irb):15> }

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • splat参数后的可选参数(Optional argument after splat argument)
    问题 这是我的程序: def calculate(*numbers, options = {}) add(numbers) if options[:add] subtract(numbers) if options[:add] == false end def add(*numbers) numbers.reduce(:+) end def subtract(*numbers) numbers.reduce(:-) end p calculate(1,2) 在第1行,它在抱怨 tests.rb:1:语法错误,意外的'=',期望的是')' def计算(*数字,选项= {}) ________________________________________________ ^ [在0.1秒内完成,退出代码为1] 我认为这可能是Ruby中默认值的问题,因为在v1.9之前,您需要按顺序拥有所有默认值-但这不应该成为问题,因为我的版本是 ruby 2.0.0p195 (2013-05-14) [i386-mingw32] 我已经尝试过对所有空间进行转置,因为在方法方面,红宝石似乎对这些东西特别,但没有骰子。 可能是我的splat变量*numbers吗? 回答1 在splat之后不能有可选参数。 splat的意思是“用完所有剩余的参数”,但是您提供了一个可选参数
  • 在Ruby中将关键字与常规参数混合?(Mixing keyword with regular arguments in Ruby?)
    问题 Ruby 2.0支持关键字参数。 我想知道,将常规参数与关键字参数混合的“规则”是什么? 这样的事情是行不通的: def some_method(a: 'first', b: 'second', c) [a, b, c] end 但这将: def some_method(c, a: 'first', b: 'second') [a, b, c] end 那么,为什么要在关键字参数之前(而不是之后)放置常规参数呢? 网络上是否有一些参考(混合关键字和常规参数)? 我似乎找不到任何东西。 回答1 Ruby中参数列表的伪正则表达式(这同样适用于方法,块和lambda文字)如下所示: mand* opt* splat? mand* (mand_kw | opt_kw)* ksplat? block? 这是一个例子: def foo(m1, m2, o1=:o1, o2=:o2, *splat, m3, m4, ok1: :ok1, mk1:, mk2:, ok2: :ok2, **ksplat, &blk) Hash[local_variables.map {|var| [var, eval(var.to_s)] }] end method(:foo).arity # => -5 method(:foo).parameters # => [[:req, :m1], [:req,
  • 如何同时使用splat和可选的哈希在ruby中定义方法? [复制](How to define a method in ruby using splat and an optional hash at the same time? [duplicate])
    问题 这个问题已经在这里有了答案: splat参数之后的可选参数(6个答案) 6年前关闭。 我可以定义这样的方法: def test(id, *ary, hash_params) # Do stuff here end 但这使hash_params参数成为hash_params参数。 这些也不起作用: def t(id, *ary, hash_params=nil) # SyntaxError: unexpected '=', expecting ')' def t(id, *ary, hash_params={}) # SyntaxError: unexpected '=', expecting ')' 有没有办法使它可选? 回答1 你不能那样做。 您必须考虑Ruby如何确定属于*ary和属于可选哈希的对象。 由于Ruby无法理解您的想法,因此上述参数组合(splat +可选)无法逻辑地解决。 您要么必须重新排列您的论点: def test(id, h, *a) 在这种情况下, h将不是可选的。 或手动编程: def test(id, *a) h = a.last.is_a?(Hash) ? a.pop : nil # ^^ Or whatever rule you see as appropriate to determine if h # should be assigned
  • Ruby-关键字参数-您可以将所有关键字参数都视为哈希吗? 如何?(Ruby - Keyword Arguments - Can you treat all of the keyword arguments as a hash? How?)
    问题 我有一个看起来像这样的方法: def method(:name => nil, :color => nil, shoe_size => nil) SomeOtherObject.some_other_method(THE HASH THAT THOSE KEYWORD ARGUMENTS WOULD MAKE) end 对于任何给定的呼叫,我都可以接受可选值的任意组合。 我喜欢命名的参数,因为我只能查看方法的签名以查看可用的选项。 我不知道上面的代码示例中的大写字母描述的内容是否存在快捷方式。 回到过去,它曾经是: def method(opts) SomeOtherObject.some_other_method(opts) end 优雅,简单,几乎是作弊。 这些关键字参数是否有快捷方式,还是我必须在方法调用中重新构造选项哈希? 回答1 是的,这是可能的,但是不是很优雅。 您将必须使用parameters方法,该方法将返回该方法的参数及其类型的数组(在这种情况下,我们只有关键字自变量)。 def foo(one: 1, two: 2, three: 3) method(__method__).parameters end #=> [[:key, :one], [:key, :two], [:key, :three]] 知道这一点
  • Ruby中具有默认值的可选参数(Optional arguments with default value in Ruby)
    问题 我想创建一个具有默认值的可选参数的函数 def my_function(a = nil, b=nil, c=500) end 并使用我只想指定的参数调用函数 my_function(b=100) 如何在Ruby 1.9.2中完成此操作? 回答1 在Ruby <2.0中,您不能执行此操作(或类似操作)。 您能做的最好的事情是: def my_function(h = {}) h[:c] ||= 500 # Use h[:a], h[:b], h[:c] ... end my_function(b: 100) 回答2 参数绑定到这样的参数: 只要在参数列表的开头有未绑定的必需参数,就从左到右绑定参数只要在参数列表的末尾有未绑定的强制性参数,就从右到左绑定参数任何剩余的参数都将绑定到可选参数,从左到右任何剩余的参数都将收集到数组中并绑定到splat参数块被包装到Proc并绑定到block参数如果有任何未绑定的参数或剩余的参数,请raise ArgumentError 这是一个例子: def foo(mand1, mand2, opt1=:opt1, opt2=:opt2, *splat, mand3, mand4, &block) p local_variables.map {|v| "#{v} = #{eval(v.to_s)}" } end foo 1, 2, 3 #
  • Optional argument after splat argument
    Here is my program: def calculate(*numbers, options = {}) add(numbers) if options[:add] subtract(numbers) if options[:add] == false end def add(*numbers) numbers.reduce(:+) end def subtract(*numbers) numbers.reduce(:-) end p calculate(1,2) On line 1, it is complaining tests.rb:1: syntax error, unexpected '=', expecting ')' def calculate(*numbers, options = {}) ________________________________________________^ [Finished in 0.1s with exit code 1] I thought it might have been a problem with default values in Ruby, because before v1.9, you were required to have all default values in order - but
  • 为什么在这里在数组定义中使用splat?(Why is the splat used inside an array definition here?)
    问题 def initialize(apps, catch=404) @apps = []; @has_app = {} apps.each { |app| add app } @catch = {} [*catch].each { |status| @catch[status] = true } end 在Rack :: Cascade的此方法中, splat(*)在[*catch]代码中起什么作用? 我认为方法参数中使用了splat来指示何时需要使用数量不确定的参数。 图示在这里有不同的含义吗? 回答1 它为捕获创建单个平面数组 我不确定是否有人完全了解splat运算符。 很多时候,它删除一个级别的“数组性”,但不会删除最后一个级别。 至少在这种情况下有可能获得它。 它为catch参数创建一个单层数组,而不管catch是单个数字还是数字数组。 >> t = [*404] => [404] >> t = [*[404,405,406]] => [404, 405, 406] 回答2 我认为理解这一点的最好方法是查看irb正在发生的事情。 因此,让我们初始化一个空哈希@catch : >> @catch = {} => {} >> @catch.class => Hash 现在,让我们看看当参数catch变为默认值404时会发生什么: >> catch=404 => 404 >>
  • Ruby 哈希等效于 JavaScript 的对象初始值设定项 ES6 速记(Ruby hash equivalent of JavaScript's object initializer ES6 shorthand)
    问题 在 JavaScript ES6 中,我们可以创建变量名成为键的对象,如下所示: > let a = 'aaa' 'aaa' > let b = 'bbb' 'bbb' > { a, b } { a:"aaa", b:"bbb" } Ruby 是否具有等效的哈希值? 澄清:显然这个问题与速记符号有关。 我正在寻找{a,b}而不是{a:a,b:b} 。 回答1 不,没有这样的速记符号。 回答2 简短的回答没有。 更长的答案 Shugo Maeda 在 2015 年为此提出了一个补丁(您可以在此处阅读有关此的详细信息:https://bugs.ruby-lang.org/issues/11105)。 当时 Matz 还没有这个想法,但将来可能愿意改变主意。 同时 - 您可以使用 Shugo 的补丁并修补您自己的 Ruby 版本以自己拥有 ES6 哈希文字! 要修补 Ruby 以添加哈希,请执行以下操作: 1) 从这里下载补丁 https://gist.github.com/thechrisoshow/1bb5708933d71e0e66a29c03cd31dcc3(目前适用于 Ruby 2.5.0) 2) 使用 RVM 安装此 Ruby 的修补版本。 IE rvm install 2.5.0 -n imphash --patch imphash.patch 然后你可以使用 RVM
  • (一元)*运算符在此Ruby代码中做什么?(What does the (unary) * operator do in this Ruby code?)
    问题 给定Ruby代码 line = "first_name=mickey;last_name=mouse;country=usa" record = Hash[*line.split(/=|;/)] 除了*运算符,我在第二行中了解所有内容-它在做什么,相关文档在哪里? (您可能会猜到,搜索这种情况非常困难...) 回答1 *是splat运算符。 它将Array扩展为参数列表,在本例中为Hash.[]方法的参数列表。 (更确切地说,它膨胀的任何对象响应to_ary / to_a ,或to_a Ruby 1.9中)。 为了说明这一点,以下两个语句是相等的: method arg1, arg2, arg3 method *[arg1, arg2, arg3] 它也可以在不同的上下文中使用,以捕获方法定义中所有剩余的方法参数。 在这种情况下,它不会扩展,但会结合在一起: def method2(*args) # args will hold Array of all arguments end 一些更详细的信息在这里。 回答2 splat运算符解压缩传递给函数的数组,以便将每个元素作为单独的参数发送给函数。 一个简单的例子: >> def func(a, b, c) >> puts a, b, c >> end => nil >> func(1, 2, 3) #we can call
  • Ruby方法和可选参数(Ruby Methods and Optional parameters)
    问题 我正在与Ruby on Rails一起玩,并且尝试创建带有可选参数的方法。 显然有很多方法可以做到这一点。 我尝试将可选参数命名为哈希,但未定义它们。 输出是不同的。 看一看: # This functions works fine! def my_info(name, options = {}) age = options[:age] || 27 weight = options[:weight] || 160 city = options[:city] || "New York" puts "My name is #{name}, my age is #{age}, my weight is #{weight} and I live in {city}" end my_info "Bill" -> My name is Bill, my age is 27, my weight is 160 and I live in New York -> OK! my_info "Bill", age: 28 -> My name is Bill, my age is 28, my weight is 160 and I live in New York -> OK! my_info "Bill", weight: 200 -> My name is Bill, my age is
  • 命名此python / ruby​​语言构造(使用数组值以满足函数参数)(Name this python/ruby language construct (using array values to satisfy function parameters))
    问题 这种语言结构叫什么? 在Python中,我可以说: def a(b,c): return b+c a(*[4,5]) 并得到9。同样在Ruby中: def a(b,c) b+c end a(*[4,5]) 当将单个数组传递给否则需要多个参数的函数时,这叫什么? *运算符的名称是什么? 还有哪些其他语言支持此炫酷功能? 回答1 Python文档将其称为“拆包参数列表”。 这是一个非常方便的功能。 在Python中,您还可以使用双星号(**)将字典(哈希)解压缩为关键字参数。 它们也可以反向工作。 我可以这样定义一个函数: def sum(*args): result = 0 for a in args: result += a return result sum(1,2) sum(9,5,7,8) sum(1.7,2.3,8.9,3.4) 将所有参数打包到任意大小的列表中。 回答2 在红宝石中,它通常被称为“ splat”。 同样在ruby中,您可以使用它来表示“列表中的所有其他元素”。 a, *rest = [1,2,3,4,5,6] a # => 1 rest # => [2, 3, 4, 5, 6] 它也可以出现在赋值运算符的任一侧: a = d, *e 在这种用法中,它有点像scheme的cdr,尽管它只需要列表的头即可。 回答3 典型的术语称为“将功能应用于列表”
  • Ruby块的最佳解释? [关闭](Best explanation of Ruby blocks? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 7年前关闭。 改善这个问题 您可以共享的Ruby块的最佳解释是什么? 用法和编写代码可能会花费很多时间? 回答1 我对此回答提供了自己的解释,并做了一些修改: Ruby中的“块”与通用编程术语“代码块”或“代码块”不同。 假装一下以下(无效的)Ruby代码实际上有效: def add10( n ) puts "#{n} + 10 = #{n+10}" end def do_something_with_digits( method ) 1.upto(9) do |i| method(i) end end do_something_with_digits( add10 ) #=> "1 + 10 = 11" #=> "2 + 10 = 12" ... #=> "9 + 10 = 19" 尽管该代码无效,但它的意图(将某些代码传递给某个方法并让该方法运行该代码)可以在Ruby中以多种方式实现。 这些方法之一是“块”。 Ruby中的Block非常非常类似于一种方法:它可以接受一些参数并为其运行代码。 每当您看到foo{ |x,y,z| ... } foo{ |x,y,z| ... }或foo do |x,y,z| ... end foo do |x
  • PowerShell 在 Invoke-Command 上生成参数列表(PowerShell Splatting the Argumentlist on Invoke-Command)
    问题 如何使用散列表中收集的参数与Invoke-Command上的ArgumentList一起使用? $CopyParams = @{ Source = 'E:\DEPARTMENTS\CBR\SHARE\Target' Destination = 'E:\DEPARTMENTS\CBR\SHARE\Target 2' Structure = 'yyyy-MM-dd' } Invoke-Command -Credential $Cred -ComputerName 'SERVER' -ScriptBlock ${Function:Copy-FilesHC} -ArgumentList @CopyParams 无论我尝试什么,它总是抱怨“来源”: Cannot validate argument on parameter 'Source'. The "Test-Path $_" validation script for the argument with value "System.Collections.Hashtable" did not return true. Determine why the validation script failed 这个博客讨论了一个类似的问题,但我无法让它工作。 对于Invoke-Command的简单Copy-Item也是如此,例如:
  • 何时在Ruby中使用关键字参数(又名命名参数)(When to use keyword arguments aka named parameters in Ruby)
    问题 Ruby 2.0.0支持关键字参数(KA),我想知道在纯Ruby的情况下此功能的好处/用例是什么,特别是从由于需要进行每次关键字匹配而导致的性能损失来看,尤其如此调用带有关键字参数的方法。 require 'benchmark' def foo(a:1,b:2,c:3) [a,b,c] end def bar(a,b,c) [a,b,c] end number = 1000000 Benchmark.bm(4) do |bm| bm.report("foo") { number.times { foo(a:7,b:8,c:9) } } bm.report("bar") { number.times { bar(7,8,9) } } end # user system total real # foo 2.797000 0.032000 2.829000 ( 2.906362) # bar 0.234000 0.000000 0.234000 ( 0.250010) 回答1 关键字参数具有一些没有人碰到过的独特优势。 首先,您没有耦合到参数的顺序。 因此,在有时候您可能会使用nil参数的情况下,它看起来要干净得多: def print_greeting(name, message = "Hello") puts "#{message}, #{name}" end print
  • double *(splat)运算符有什么作用(What does a double * (splat) operator do)
    问题 您是否看到过这样声明的函数? def foo a, **b ... end 我知道单个*是splat运算符。 **是什么意思? 回答1 Ruby 2.0引入了关键字参数,而**作用类似于* ,但关键字参数却适用。 它返回带有键/值对的哈希值。 对于此代码: def foo(a, *b, **c) [a, b, c] end 这是一个演示: > foo 10 => [10, [], {}] > foo 10, 20, 30 => [10, [20, 30], {}] > foo 10, 20, 30, d: 40, e: 50 => [10, [20, 30], {:d=>40, :e=>50}] > foo 10, d: 40, e: 50 => [10, [], {:d=>40, :e=>50}] 回答2 这是从Ruby 2.0开始可用的double splat运算符。 它捕获所有关键字参数(也可以是一个简单的哈希,这是在关键字参数成为Ruby语言一部分之前模拟关键字参数的惯用方式) def my_method(**options) puts options.inspect end my_method(key: "value") 上面的代码将{key:value}打印到控制台。 就像单个splat运算符捕获所有常规参数一样,但是您得到的不是hash而是数组。
  • Ruby-将变量优雅地转换为数组(如果还没有数组的话)(Ruby - elegantly convert variable to an array if not an array already)
    问题 给定一个数组,则单个元素或nil获得一个数组-后两个分别为单个元素数组和一个空数组。 我错误地认为Ruby可以这样工作: [1,2,3].to_a #= [1,2,3] # Already an array, so no change 1.to_a #= [1] # Creates an array and adds element nil.to_a #= [] # Creates empty array 但是,您真正得到的是: [1,2,3].to_a #= [1,2,3] # Hooray 1.to_a #= NoMethodError # Do not want nil.to_a #= [] # Hooray 因此,要解决此问题,我要么需要使用另一种方法,要么可以通过修改我打算使用的所有类的to_a方法来元程序-这对我来说不是一个选择。 因此它是一种方法: result = nums.class == "Array".constantize ? nums : (nums.class == "NilClass".constantize ? [] : ([]<<nums)) 问题是,这有点混乱。 是否有一种优雅的方法? (如果这是解决该问题的类似Ruby的方法,我会感到惊讶) 这有什么应用程序? 为什么还要转换为数组? 在Rails的ActiveRecord中
  • Python中的*args和**kwargs是什么?该如何使用?
    来源:Pexels 在编程中,函数就是生命! 作为使用Python的新手——无论是编程新手,还是熟悉另一语言的人——都需要学习函数定义中的参数数目是否和想要传达的变元数目匹配。 ​! 这是基础性知识——有助于了解这个世界。 然而,接触到函数定义中的*args和**kwargs时,也会让新手刚开始就遇到心理障碍。 在Python中的代码中经常会见到这两个词 args 和 kwargs,前面通常还会加上一个或者两个星号。 别被这些语句所绊倒。其实这些并不是什么超级特殊的参数,也并不奇特,只是编程人员约定的变量名字,args 是 arguments 的缩写,表示位置参数;kwargs 是 keyword arguments 的缩写,表示关键字参数。 这其实就是 Python 中可变参数的两种形式,并且 *args 必须放在 **kwargs 的前面,因为位置参数在关键字参数的前面。 接下来,我们就具体学学如何使用它们。 位置参数vs关键字参数 为了学习什么是*args和**kwargs,我们需要区分两个概念。 首先,分清楚位置参数和关键字参数的区别。在最基本的函数中,做一个匹配游戏——参数1与参数1匹配,参数2与参数2匹配,诸如此类。 def printThese(a,b,c): print(a, "is stored in a") print(b, "is stored in b")
  • Ruby 中的 Splat 运算符(快速排序示例)(Splat operator in Ruby (a quicksort example))
    问题 你好,我正在学习一些 Ruby 代码。 在 Ruby 中实现快速排序: 1 def qsort(lst) 2 return [] if lst.empty? 3 x, *xs = *lst 4 less, more = xs.partition{|y| y < x} 5 qsort(less) + [x] + qsort(more) 6 end 鉴于: lst = [1, 2, 3, 4, 5] x, *xs = *lst 我不知道我是否理解第 3 行的正确操作: 根据我的观察和实验,这会将1从lst分配给x ,并将lst的其余部分分配给xs 。 我还发现这两个正在做同样的事情: x, *xs = *lst 相当于 x, *xs = lst 我的问题是,这个不错的功能的名称是什么(我会在之后编辑标题以适应)? 然后我可以自己研究更多关于这个 Ruby 特性的信息。 对不起,如果这是一个重复的问题,因为我不知道搜索这个问题的关键字。 回答1 此功能的名称在 Ruby 中称为splat运算符。 回答2 Ruby、Groovy 和 Perl 中的 splat 运算符允许您在参数和数组之间切换:它将列表拆分为一系列参数,或收集一系列参数以填充数组。 来自 4 行代码。 回答3 这个说法 x, *xs = *lst 对我来说没有多大意义,但这些确实: x, *xs = [1, 2, 3
  • What is the standalone splat operator (*) used for in Ruby?
    I just came across this example where the splat operator is used by itself in a method definition: def print_pair(a,b,*) puts "#{a} and #{b}" end print_pair(1,2,3,:cake,7) #=> 1 and 2 It is clear what and why you would use it in a context like so: def arguments_and_opts(*args, opts) puts "arguments: #{args} options: #{opts}" end arguments_and_opts(1,2,3, a: 5) #=> arguments: [1, 2, 3] options: {:a=>5} But why and how would you use it in the first example? Since it is defined in the Ruby specs there must be a usecase for it?
  • Ruby - 测试数组(Ruby - test for array)
    问题 什么是正确的方法: is_array("something") # => false (or 1) is_array(["something", "else"]) # => true (or > 1) 或获取其中的项目数? 回答1 您可能想使用 kind_of()。 >> s = "something" => "something" >> s.kind_of?(Array) => false >> s = ["something", "else"] => ["something", "else"] >> s.kind_of?(Array) => true 回答2 你确定它需要是一个数组吗? 您也许可以使用respond_to?(method)以便您的代码可以用于不一定是数组的类似事物(也许是其他一些可编号的事物)。 如果您确实需要一个array ,那么描述Array#kind\_of? 方法最好。 ['hello'].respond_to?('each') 回答3 无需测试Array,只需将您获得的任何内容转换为一级Array,因此您的代码只需要处理一种情况。 t = [*something] # or... t = Array(something) # or... def f *x ... end Ruby 有多种方法来协调 API,该 API