你见过像这样声明的函数吗?
def foo a, **b
...
end
Run Code Online (Sandbox Code Playgroud)
我知道单个*是splat运算符.什么**意思?
运营商的正确名称是什么*,如function(*args)?解压缩,解压缩,其他什么?
鉴于Ruby代码
line = "first_name=mickey;last_name=mouse;country=usa"
record = Hash[*line.split(/=|;/)]
Run Code Online (Sandbox Code Playgroud)
除了*操作员之外,我理解第二行中的所有内容 - 它在做什么以及文档在哪里?(正如你可能猜到的那样,寻找这个案子很难......)
考虑例如
squares = *map((2).__rpow__, range(5)),
squares
# (0, 1, 4, 9, 16)
*squares, = map((2).__rpow__, range(5))
squares
# [0, 1, 4, 9, 16]
Run Code Online (Sandbox Code Playgroud)
因此,在所有其他条件相等的情况下,当我们在lhs上进行排序时,会得到一个列表,而当我们在rhss上进行布局时,会得到一个元组。
为什么?
这是设计使然吗,如果是的话,其原理是什么?否则,是否有任何技术原因?还是只是这样,没有特殊原因?
可能重复:
*运算符在Ruby中对此字符串执行的操作是什么
可能在其他地方有答案,但我只是不知道如何找到它...
如果我是对的,*如果在函数定义中使用,则表示多个参数:
def hero(name, *super_powers)
Run Code Online (Sandbox Code Playgroud)
但是*在代码中做了什么呢:
Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] # => {:first_name=>"Shane", :last_name=>"Harvie"}
Run Code Online (Sandbox Code Playgroud) Splats很酷.它们不只是用于爆炸阵列,尽管这很有趣.它们还可以转换为数组并展平数组(请参阅http://github.com/mischa/splat/tree/master以获取他们所做的详尽列表.)
看起来无法对splat执行其他操作,但在1.8.6/1.9中,以下代码抛出"意外的tSTAR":
foo = bar || *zap #=> unexpected tSTAR
虽然这有效:
foo = *zap || bar #=> works, but of limited value
splat在哪里可以出现在表达式中?
我正在使用Ruby on Rails 3,我想知道*在函数参数附近是否存在运算符,并了解其在其他场景中的用法.
示例场景(此方法来自Ruby on Rails 3框架):
def find(*args)
return to_a.find { |*block_args| yield(*block_args) } if block_given?
options = args.extract_options!
if options.present?
apply_finder_options(options).find(*args)
else
case args.first
when :first, :last, :all
send(args.first)
else
find_with_ids(*args)
end
end
end
Run Code Online (Sandbox Code Playgroud) 在Python和Ruby(以及其他人,我敢肯定).你可以在枚举前加上*("splat")来将它用作参数列表.例如,在Python中:
>>> def foo(a,b): return a + b
>>> foo(1,2)
3
>>> tup = (1,2)
>>> foo(*tup)
3
Run Code Online (Sandbox Code Playgroud)
Haskell中有类似的东西吗?我认为由于它们的任意长度它不适用于列表,但我觉得有了元组它应该工作.这是我想要的一个例子:
ghci> let f a b = a + b
ghci> :t f
f :: Num a => a -> a -> a
ghci> f 1 2
3
ghci> let tuple = (1,2)
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个允许我这样做的操作符(或函数):
ghci> f `op` tuple
3
Run Code Online (Sandbox Code Playgroud)
我看到(<*>)被称为"splat",但它似乎并不是指与其他语言中的splat相同的东西.无论如何我试过了:
ghci> import Control.Applicative
ghci> f <*> tuple
<interactive>:1:7:
Couldn't match expected type `b0 -> b0'
with actual type …Run Code Online (Sandbox Code Playgroud) 给出例如:
scala> def pipes(strings:String*) = strings.toList.mkString("|")
Run Code Online (Sandbox Code Playgroud)
我可以正常打电话:
scala> pipes("foo", "bar")
res1: String = foo|bar
Run Code Online (Sandbox Code Playgroud)
或者用splat:
scala> val args = List("a","b","c")
scala> pipes(args:_*)
res2: String = a|b|c
Run Code Online (Sandbox Code Playgroud)
但是我可以使用splat为除了varargs参数之外的任何东西提供参数吗?例如,我想做类似的事情:
scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> pipeItAfterIncrementing(args:_*)
Run Code Online (Sandbox Code Playgroud)
这不起作用,但有没有办法实现从单个对象提供多个参数的相同效果,无论是元组还是其他东西?是否有任何理由不能为元组实现,因为它们的长度和类型在编译时都是已知的?
我今天在浏览Rails代码时偶然发现了这个片段:
new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
Run Code Online (Sandbox Code Playgroud)
什么是星号 - 双结肠(如果你愿意的话,还是splat-le-colon)*::Date呢?
据推测,它与特定命名空间的Date类的范围有关......但是,作者必须包含它而不仅仅是使用标准Date类.