我想明白之间的差别*(1..9),并[*1..9]
如果我将它们分配给变量,它们的工作方式相同
splat1 = *(1..9) # splat1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
splat2 = [*1..9] # splat2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
但是,事情变得奇怪,当我尝试使用*(1..9)和[*1..9]直接.
*(1..9).map{|a| a.to_s} # syntax error, unexpected '\n', expecting tCOLON2 or '[' or '.'
[*1..9].map{|a| a.to_s} # ["1", "2", "3"...]
Run Code Online (Sandbox Code Playgroud)
我猜测问题的一部分是运营商的预测?但我不确定发生了什么.为什么我无法使用*(1..9)我可以使用的相同功能[*1..9]?
我注意到我发现**Ruby 2.1.1中的(双splat)运算符是一个非常令人惊讶的行为.
当在a之前使用键值对时**hash,哈希保持不变; 但是,当键值对仅在之后使用时**hash,哈希值将被永久修改.
h = { b: 2 }
{ a: 1, **h } # => { a: 1, b: 2 }
h # => { b: 2 }
{ a: 1, **h, c: 3 } # => { a: 1, b: 2, c: 3 }
h # => { b: 2 }
{ **h, c: 3 } # => { b: 2, c: 3 }
h # => { b: 2, c: …Run Code Online (Sandbox Code Playgroud) 我有一个方法应该采用任何类的1+参数,类似于Array#push:
def my_push(*objects)
raise ArgumentError, 'Needs 1+ arguments' if objects.empty?
objects.each do |obj|
puts "An object was pushed: #{obj.inspect}"
@my_array.push obj
end
end
Run Code Online (Sandbox Code Playgroud)
使用YARD语法记录方法参数的最佳方法是什么?
编辑:
我意识到我原来的问题有点过于模糊,并没有明确说明我在寻找什么.
一个更好的问题是,当使用splatted参数时,在YARD中指定方法的arity(在这种情况下为1-∞)的最佳方法是什么?我知道我可以在文本中指定它,但似乎应该有一个标签或类似的东西来指定arity.
注意:在GitHub上的 mischa的splat有很多很酷的交互式示例*在行动中.
通过谷歌搜索,我发现在Ruby中迭代一系列数字的一种方法(你的经典C风格的循环)
for (i = first; i <= last; i++) {
whatever(i);
}
Run Code Online (Sandbox Code Playgroud)
是做这样的事情
[*first..last].each do |i|
whatever i
end
Run Code Online (Sandbox Code Playgroud)
但是这种[*first..last]语法究竟发生了什么?我一起玩irb,我看到了这个:
ruby-1.9.2-p180 :001 > 0..5
=> 0..5
ruby-1.9.2-p180 :002 > [0..5]
=> [0..5]
ruby-1.9.2-p180 :003 > [*0..5]
=> [0, 1, 2, 3, 4, 5]
ruby-1.9.2-p180 :004 > *0..5
SyntaxError: (irb):4: syntax error, unexpected tDOT2, expecting tCOLON2 or '[' or '.'
*0..5
^
Run Code Online (Sandbox Code Playgroud)
我在网上看到的所有内容都讨论了一元星号对扩展和折叠传递给方法的参数很有用,对于可变长度参数列表非常有用
def foo(*bar)
bar
end
foo 'tater' # => ["tater"] …Run Code Online (Sandbox Code Playgroud) 在Ruby中,我可以使用像这样的位置参数的数组元素来调用方法
method(fixed_arg1, fixed_arg2, *array_of_additional_args)
Run Code Online (Sandbox Code Playgroud)
这里"*"运算符扩展了数组.
我试图在CoffeeScript中做同样的事情,但还没找到办法.具体来说,我想在调用jQuery函数时传递其他参数
$('#my-element').toggle(true, *config.toggleOptions)
Run Code Online (Sandbox Code Playgroud)
显然,上面的语法不起作用,我正在寻找一种方法.
在http://learnxinyminutes.com/docs/julia/上阅读Julia时,我发现了这个:
# You can define functions that take a variable number of
# positional arguments
function varargs(args...)
return args
# use the keyword return to return anywhere in the function
end
# => varargs (generic function with 1 method)
varargs(1,2,3) # => (1,2,3)
# The ... is called a splat.
# We just used it in a function definition.
# It can also be used in a fuction call,
# where it will splat an Array or Tuple's …Run Code Online (Sandbox Code Playgroud) 我正在使用Visual Studio 13社区.创建了一个简单的WinForms项目,创建了一个空类并继承了ReactiveObject.我已经使用NuGet安装了reactivui-winforms 6.5.0.我可以看到ver 1.0.0已安装并且Splat在引用中.
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI;
using Splat;
namespace ReactiveSplatTest
{
class ReactiveObjectTest : ReactiveObject
{
}
}
Run Code Online (Sandbox Code Playgroud)
在Splat引用的属性中,路径是:
c:\users\rick reynolds\documents\visual studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45\Splat.dll
Run Code Online (Sandbox Code Playgroud)
我已经证实这是正确的道路.那个文件Splat.dll确实存在.
C:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45
Run Code Online (Sandbox Code Playgroud)
我每次建立时都会收到此警告和错误...
警告1:
Reference to type 'Splat.IEnableLogger' claims it is defined in 'c:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45\Splat.dll',
but it could not be found c:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\reactiveui-
core.6.5.0\lib\Net45\ReactiveUI.dll ReactiveSplatTest
Run Code Online (Sandbox Code Playgroud)
错误2:
The base class or interface 'Splat.IEnableLogger' in assembly 'Splat,
Version=1.6.2.0, Culture=neutral, PublicKeyToken=null' …Run Code Online (Sandbox Code Playgroud) 我发现它可以在Ruby中使用,但我从我在Python中所做的事情中认识到它; "splat"运算符.长话短说,我想知道是否有一种更简单的方法来完成我目前的工作,模仿"splat"操作符的作用.
我做了一个中心方法,其余的可以打电话,因为我意识到我有几个非常相似的方法,除了一些小的东西,他们都在做同样的事情.这是方法签名:
private String callScript(String scriptLocation, String... extraArgs) throws Exception {
Run Code Online (Sandbox Code Playgroud)
我想要至少一个参数(the scriptLocation),然后允许任意数量的额外参数.我最终做的就是创造一个ProcessBuilder.我的愿望是做这样的事情:
ProcessBuilder pb = new ProcessBuilder("something", scriptLocation, /* extraArgs */);
Run Code Online (Sandbox Code Playgroud)
但是,当然,ProcessBuilder构造函数只接受以下内容:
List<String>String[]String...所以我的方法显然不起作用.
我目前的解决方法,据我所知,工作正常:
List<String> finalArgs = new ArrayList<String>();
finalArgs.add("something");
finalArgs.add(scriptLocation);
finalArgs.addAll(Arrays.asList(extraArgs));
ProcessBuilder pb = new ProcessBuilder(finalArgs);
Run Code Online (Sandbox Code Playgroud)
(是的,我知道我不必使用List,只能做一个String[])
(是的,我知道我可以循环extraArgs并将它们finalArgs单独添加,而不必使用addAll和Arrays.asList())
(是的,我知道我可以通过返回与变量参数结合的某些参数来创建一个有效完成我的变通方法的函数)
所以我猜这些最后三个陈述之外,还有什么可以实现这一点吗?
为什么Ruby(2.0)使用splat参数处理/块的行为与方法和lambda不同?
def foo (ids, *args)
p ids
end
foo([1,2,3]) # => [1, 2, 3]
bar = lambda do |ids, *args|
p ids
end
bar.call([1,2,3]) # => [1, 2, 3]
baz = proc do |ids, *args|
p ids
end
baz.call([1,2,3]) # => 1
def qux (ids, *args)
yield ids, *args
end
qux([1,2,3]) { |ids, *args| p ids } # => 1
Run Code Online (Sandbox Code Playgroud)
以下是对此行为的确认,但没有解释:http: //makandracards.com/makandra/20641-careful-when-calling-a-ruby-block-with-an-array
splat ×10
ruby ×6
syntax ×2
arguments ×1
arrays ×1
block ×1
coffeescript ×1
double-splat ×1
hash ×1
java ×1
julia ×1
lambda ×1
operators ×1
parameters ×1
proc ×1
reactiveui ×1
tuples ×1
winforms ×1
yard ×1