7

以下のコード スニペットで何が起こっているのか正確にはわかりません。

>> a, b = ["ho", "hey"]
=> ["ho", "hey"]
>> a
=> "ho"
>> b
=> "hey"    
>> c, d = "foo", "bar"
=> ["foo", "bar"]
>> c 
=> "foo"
>> d
=> "bar"
>> a, b = ["blerg"], ["baz"]
=> [["blerg"], ["baz"]]
>> a
=> ["blerg"]
>> b 
=> ["baz"]

1 行目が返らないのはなぜa => ["ho"]ですか?

舞台裏では、これら 3 つの割り当て ( a, b = ["ho", "hey"]c, d = "foo", "bar"a, b = ["blerg"], ["baz"]) の違いは何ですか?

4

4 に答える 4

11
a, b = ["ho", "hey"] 

a配列の最初の要素である文字列「ho」が割り当てられます。何も変なことはありません。

a, b = ["blerg"], ["baz"]

a, b = [["blerg"], ["baz"]]

戻り値からわかるように、これら2つは同じです。したがって、aには最初の要素が割り当てられます。これは、次の1つの要素を持つ配列です["blerg"]

同様に、

c, d = "foo", "bar"

と同じです

c, d = ["foo", "bar"]
于 2013-02-16T18:48:35.043 に答える
7

Ruby では= 、左側に変数のリスト、右側に式のリストを取ります。最初の変数を最初の式の値に、2 番目の変数を 2 番目の式の値に、というように割り当てます。式よりも多くの変数がある場合、残りの変数には値が割り当てられますnil

> a, b, c, d = "foo", 2+3, Array.new(2, 3), [:c, :d]
> a     # => "foo"
> b     # => 5
> c     # => [3, 3]
> d     # => [:c, :d]
> e     # => nil

2 つの例外があります。

左側には変数が 1 つだけあり、右側には複数の式があります

この場合、上記のルールは、変数が右側の最初の式の値に設定されることを示しています。代わりに、変数は右側の式の値で構成される配列に設定されます。以下の例では、 だけではなくa、値を取得しています。[:b, :c]:b

> a = :b, :c
> a    # => [:b, :c]

これは次と同等です。

> *a = :b , :c
> a    # => [:b, :c]

他の例外:

左側には複数の変数があり、右側には式が 1 つしかなく、配列です。

繰り返しますが、元のルールは、最初の変数がその配列全体に設定され、残りの変数は nil になることを意味します。ただし、その配列は事実上、その要素のリストに置き換えられてしまい=、最初に説明した「デフォルト」の動作に戻ります。

> a, b, c = [:d, [:e, :f]]
> a    # => :d
> b    # => [:e, :f]
> c    # => nil

これはa, b, c = *[:d, [:e, :f]]、または単にa, b, c = :d, [:e, :f]

于 2013-02-16T20:23:38.493 に答える
0

Ruby 言語の代入演算子は、複数の代入 (別名: 並列代入) を許可します。

代入演算子 (=) の左側にある左側の変数または属性を左辺値と言い、右側の値を右辺値とします。

複数の割り当てにより、カンマ区切りのリストを別のリストに割り当てることができ、左側の対応する変数が右側から対応する値を取得します

最初の並列割り当て

a, b = ["ho", "hey"]

最後の右辺値が配列の場合は、アスタリスクを前に付けることができます。これにより、効果的にその構成要素の値に展開されます。配列が自動的に拡張される右側にあるのが右辺値のみの場合、アスタリスクは必要ありません。

理解を深めるために、次のことを試してください。

>> a,b,c =  "1",*["ho", "hey"]
=> ["1", "ho", "hey"]
>> a
=> "1"
>> b
=> "ho"
>> c
=> "hey"

もう一度見てみましょう:

>> a,b,c =  "1",["ho", "hey"]
=> ["1", ["ho", "hey"]]
>> a
=> "1"
>> b
=> ["ho", "hey"]
>> c
=> nil

ご覧のとおり、配列の前に * を付けないと、配列は展開されません。

2 番目の並列割り当て

c, d = "foo", "bar"

「foo」、「bar」は 、左側の対応する変数に割り当てられた2 つのリテラル文字列です。

3 番目の並列割り当て

a, b = ["blerg"], ["baz"])?

["blerg"]および["baz"] 2 つのArrayであり、それぞれがクラスStringの 1 つの要素を含みます。

したがって、各「単一文字列の配列」は、左側の対応する変数に割り当てられます。

于 2013-02-16T19:47:55.957 に答える
0

あなたが指摘した例では、複数代入の右側で2つの異なる構造が使用されています:

単純な配列からの複数代入

array = ["item1", "item2"]
a, b = array
# a => "item1"
# b => "item2"

要素自体が単一要素配列 (別名: 多次元配列) である配列からの複数代入

array = [["item1"], ["item2"]]
a, b = array
# a => ["item1"]
# b => ["item2"]

複数代入は、多次元配列の最初のレベルのみをアンラップし、それらの要素を式の左側の複数の変数に代入できるようにします。したがって、多次元配列でこれを行うと、最初の要素 wich を取り、 に["item1"]代入しa、次の要素に移動します。これは["item2"]に代入しbます。複数の割り当ては、多次元配列を「深く掘り下げる」のではなく、要素の最初のレベルから割り当てを実行します。

于 2013-02-16T18:55:49.727 に答える