還記在寫引數Argument文章有寫到當前墜一個星符號*
的會得到陣列
那換成兩個星號呢**
?今天就來認識單星星與雙星星吧!
符號*single splat
利用方法來看,結果會得到一個空的[]
Array,它會將未指定的引數會被集合起來轉成一組陣列。
def splat(*single splat)
single splat
end
p splat # []
利用最簡單的例子來看
a, b = [1, 2]
> a # => 1
> b # => 2
# a,b只會拿到陣列中前兩個值
a, b = [1, 2, 3, 4]
> a # => 1
> b # => 2
# 可是當我們加上*
a, *other = [1, 2, 3, 4]
> a # => 1
> other # => [2, 3, 4]
多個引觀察輸出結果,*
會把所有接收到的引數裝在一個陣列裡。
def say_hello(*students)
students.each { |student| puts "Hi, #{student}" }
end
say_hello("Ruby","Sophia","Dora","Webber","Jimmy","Nina")
# Hi, Ruby
# Hi, Sophia
# Hi, Dora
# Hi, Webber
# Hi, Jimmy
當我們拿到一筆資料,我們可以利用*
轉Array格式
def my_pet(*pet)
p pet
end
my_pet :cat, 15, name: :Meeks # [:cat, 15, {:name=>:Meeks}]
也可以將陣列反轉成清單
def say_hello(child, friend)
puts "Hello, #{friend}. My name is #{child}"
end
name = %w(Sophia Nina) # Hello, Nina. My name is Sophia.
name = %w(Sophia Nina Amy) # ArgumentError
say_hello *name
此時在轉換的過程,必須要注意陣列元素的數量,否則會噴出ArgumentError的錯誤訊息喔!
符號**double splat
利用方法來看,結果會得到一個空的{}
Hash
def splat(**double_splat)
double_splat
end
p splat # {}
此時我就有些疑問了,它是不是跟陣列一樣,專門收未指定的引數呢?
我們從以下例子來看
def splat(a, **h)
[a, h]
end
p splat(0) # [0, {}]
p splat(0, 1) # ArgumentError
p splat(0, a: 1) # [0, {:a=>1}]
p splat(0, a: 1, b: 2) # [0, {:a=>1, :b=>2}]
有發現嗎?當引數a: 1
是一個key與value的組合為hash時,它就可以往**
裡面塞了
如果位指定的引數不是hash則會出現ArgumentError
那如過全部混在一起呢?
def splat(a, *b, **c)
[a, b, c]
end
p splat(0, 1, 2, 3, a: 4, b: 5, c: 6)
p splat(0, a: 4, b: 5, c: 6, 1, 2, 3)
# [0, [1, 2, 3], {:a=>4, :b=>5, :c=>6}]
# syntax error
第二行引數內容是一樣的,不過我將它位置順序調換,發現換位置之後出現syntax error的錯誤訊息,所以之後在使用時注意順序喔!
參考連結:
Ruby面試精選30題 - Day28 Ruby的 ** (double splat) operator