問題の背景:
スライスは、Perlの強力な特徴であり、配列やハッシュから一度に複数の要素を取り出したり、割り当てたりできる機能です。スライスのメカニズムは初期のPerlバージョンから存在し、Pythonと似た構文をサポートしていますが、実行やコンテキストには独自の特徴があります。
問題点:
スライスの主な難しさは、配列とハッシュのリストスライスを区別すること、スカラ/リストコンテキストの違い、特に同じ配列やハッシュへのスライスを通じた割り当てにおける「微細な」ニュアンスです。重要な点は、スライスで構造を更新する場合、リストの自動展開によって思わぬ結果が生じる可能性があることです。
解決策:
スライスは意識的に使用してください。データのコピーが必要な場合は、リストの明示的なクローンを使用してください。読み取りと書き込みの交差を避け、スライスが関数の引数や式の要素として使用される場合には、スカラ/リストコンテキストに注意を払ってください。
コード例:
my @array = (10, 20, 30, 40, 50); my @slice = @array[1, 3]; # (20, 40) @array[0, 2] = (100, 300); # @arrayは現在(100, 20, 300, 40, 50) my %hash = (foo => 1, bar => 2, baz => 3); my @vals = @hash{"foo", "baz"}; # (1, 3)
重要な特徴:
騙しの質問 1: スライス @array[2, 4] からスカラ値を取得することはできますか? $val = @array[2, 4] という形で?
いいえ、この場合 $val は要素の数(リストの長さ)になります、1つの要素の値にはなりません。単一のインデックスを介して個々の要素にアクセスするのが正しいです: $array[2]。
騙しの質問 2: スライスに重複するインデックスがある場合、何が保存されますか?
連続的な再割り当てが行われ、左から右への割り当てが行われるので、最後の値が勝ちます。例えば:
@array[0,0] = (1,2); # $array[0] == 2
騙しの質問 3: 右と左で異なる数の要素を持つスライスを割り当てることができますか?
できます。右側が少ない場合、残りは undef になります。多い場合は余分なものは無視されます。通常、これは見つけにくいエラーの原因になります。
開発者は次のように値を割り当てます: @array[2, 3] = ("foo");
両方の要素が "foo" を取得することを期待しましたが、$array[3] は undef になりました。
長所:
短所:
値をマッピングするために map 関数を使用します: @array[2, 3] = map { "foo" } (2, 3);
長所:
短所: