Die Geschichte der Frage:
Slices (Teilmengen) sind eine mächtige Eigenschaft von Perl, die es ermöglicht, eine Gruppe von Elementen aus einem Array oder Hash in einer einzigen Operation zu extrahieren oder zuzuweisen. Der Slices-Mechanismus existiert fast seit den ersten Versionen von Perl, unterstützt eine ähnliche Syntax wie die Programmiersprache Python, hat jedoch seine eigenen Ausführungseigenschaften und Kontexte.
Das Problem:
Die größte Schwierigkeit mit Slices besteht darin, zwischen Array- und Hash-Slices zu unterscheiden, ihren skalaren/listenhaften Kontext sowie die „feinen“ Nuancen bei der Zuweisung über einen Slice (insbesondere wenn die Zuweisung an dieselben Arrays oder Hashes erfolgt oder sich wiederholende Indizes verwendet werden). Ein wichtiger Punkt ist, dass bei der Aktualisierung von Strukturen mit Slices leicht unerwartete Ergebnisse aufgrund der automatischen Listenexpansion entstehen können.
Die Lösung:
Verwenden Sie Slices nur bewusst. Wenn Sie eine Kopie der Daten machen müssen, verwenden Sie eine explizite Listenkopie. Vermeiden Sie Überschneidungen beim Lesen und Schreiben und achten Sie bewusst auf den skalarischen/listenhaften Kontext, wenn der Slice als Funktionsargument oder Element in einem Ausdruck verwendet wird.
Beispielcode:
my @array = (10, 20, 30, 40, 50); my @slice = @array[1, 3]; # (20, 40) @array[0, 2] = (100, 300); # @array ist jetzt (100, 20, 300, 40, 50) my %hash = (foo => 1, bar => 2, baz => 3); my @vals = @hash{"foo", "baz"}; # (1, 3)
Hauptmerkmale:
Frage mit Haken 1: Kann man einen „skalaren“ Wert aus dem Slice @array[2, 4] so erhalten: $val = @array[2, 4]?
Nein, $val wäre in diesem Fall die Anzahl der Elemente (Länge der Liste) und nicht der Wert eines einzelnen Elements. Richtige Aufrufe der einzelnen Elemente sollten über einzelne Indizes erfolgen: $array[2].
Frage mit Haken 2: Was passiert, wenn im Slice wiederholte Indizes vorhanden sind?
Es passiert eine sequenzielle Neuzuweisung: Die Zuweisung erfolgt für jeden Index von links nach rechts, der letzte gewinnt. Zum Beispiel:
@array[0,0] = (1,2); # $array[0] == 2
Frage mit Haken 3: Kann man Slices mit unterschiedlicher Anzahl von Elementen rechts und links zuweisen?
Ja, wenn rechts weniger Elemente vorhanden sind, erhalten die verbleibenden undef. Wenn mehr vorhanden sind — werden die überschüssigen ignoriert. Dies ist oft eine Quelle für schwer zu entdeckende Fehler.
Der Entwickler weist Werte zu: @array[2, 3] = ("foo");
Er erwartete, dass beide Elemente "foo" erhalten, aber $array[3] wurde undef.
Vorteile:
Nachteile:
Verwendet die Funktion map für die Zuordnung von Werten: @array[2, 3] = map { "foo" } (2, 3);
Vorteile:
Nachteile: