shift#
Αφαιρεί και επιστρέφει το πρώτο στοιχείο ενός πίνακα.
Η shift μεταλλάσσει το όρισμά της: αφαιρεί το στοιχείο στη θέση 0, μετατοπίζει κάθε υπόλοιπο στοιχείο κάτω κατά μία θέση, και επιστρέφει την τιμή που αφαιρέθηκε. Ο πίνακας συρρικνώνεται κατά ένα. Αν ο πίνακας είναι κενός, δεν αφαιρείται τίποτα και επιστρέφεται undef.
Σύνοψη#
shift @arr
shift @$aref
shift # @_ inside a sub, @ARGV outside
Τι επιστρέφεται#
Το βαθμωτό που βρισκόταν στη θέση 0, ή undef αν ο πίνακας ήταν κενός. Επειδή το undef είναι επίσης νόμιμο στοιχείο πίνακα, μια σκέτη επιστροφή undef δεν σημαίνει από μόνη της ότι ο πίνακας ήταν κενός - χρησιμοποιήστε scalar @arr ή προηγούμενο έλεγχο defined όταν η διάκριση έχει σημασία:
my @arr = (undef, 'two');
my $item = shift @arr; # undef - but @arr was not empty
Προεπιλεγμένος πίνακας: @ARGV έναντι @_#
Όταν καλείται χωρίς όρισμα, η shift επιλέγει τον πίνακά της από το περιβάλλον συγκείμενο:
Μέσα σε κατονομασμένη ή ανώνυμη υπορουτίνα -
@_. Αυτός είναι ο ιδιωματικός τρόπος για να καταναλώνετε ορίσματα κατά θέση ένα-ένα.Outside any sub (including in the file scope of a script, and in
eval STRING,BEGIN,INIT,CHECK,UNITCHECK,ENDblocks)@ARGV. This is how top-of-script argument consumption is usually written.
Η επιλογή γίνεται κατά τη μεταγλώττιση βάσει της λεξιλογικής θέσης, όχι κατά τον χρόνο εκτέλεσης. Μια shift μέσα σε sub στοχεύει πάντα το @_ ακόμα κι αν η sub καλείται από εμβέλεια αρχείου.
Παραδείγματα#
Κατανάλωση ενός ορίσματος κατά θέση μέσα σε μέθοδο. Αυτή είναι η κανονική πρώτη γραμμή σχεδόν κάθε αντικειμενοστραφούς μεθόδου της Perl:
sub greet {
my $self = shift;
my $name = shift;
return "hello, $name, from $self";
}
Η ίδια μέθοδος γραμμένη με τομή @_ που αναλύεται ως λίστα. Και οι δύο μορφές είναι ιδιωματικές· η shift υπερισχύει όταν θέλετε να αποσπάσετε τον επικαλούμενο πριν αποφασίσετε τι θα κάνετε με το υπόλοιπο @_:
sub greet {
my ($self, $name) = @_;
return "hello, $name, from $self";
}
Κατανάλωση του @ARGV στην κορυφή ενός σεναρίου, ένα όρισμα τη φορά:
my $mode = shift // 'default'; # first CLI arg, or 'default'
my $path = shift // die "need a path\n";
# @ARGV now holds whatever is left
Μια ουρά FIFO: push στην ουρά, shift από την κεφαλή:
my @queue;
push @queue, 'a', 'b', 'c';
while (defined(my $job = shift @queue)) {
handle($job);
}
Αποαναφορά αναφοράς πίνακα επιτόπου - η shift λειτουργεί στο @$aref ακριβώς όπως σε κατονομασμένο πίνακα:
my $aref = [10, 20, 30];
my $head = shift @$aref; # 10, $aref now [20, 30]
Οριακές περιπτώσεις#
Κενός πίνακας: επιστρέφει
undefκαι αφήνει τον πίνακα ανέγγιχτο. Ηshiftσε κενό πίνακα δεν είναι σφάλμα.Η πολυπλοκότητα είναι O(n): κάθε υπόλοιπο στοιχείο μετακινείται κάτω κατά μία θέση. Για μεγάλους πίνακες που χρησιμοποιούνται ως ουρές αυτό συσσωρεύεται. Όταν δεν απαιτείται διάταξη FIFO, η
popείναι O(1)· όταν απαιτείται, σκεφτείτε δομή δεδομένων τύπου deque ή ζεύγος στοιβών αντί να κάνετεshiftσε πίνακα ενός εκατομμυρίου στοιχείων μέσα σε βρόχο.Η
shiftχωρίς όρισμα είναι ευαίσθητη στο περιβάλλον βάσει λεξιλογικής θέσης: μέσα σε sub στοχεύει το@_, έξω στοχεύει το@ARGV. Η μετακίνηση μιας γραμμής κώδικα μεταξύ αυτών των εμβελειών αλλάζει σιωπηρά ποιον πίνακα μεταλλάσσει.Tied πίνακες: η
shiftκαλεί τη μέθοδοSHIFTστο tied αντικείμενο αν είναι ορισμένη· διαφορετικά καταφεύγει σεFETCHστο στοιχείο0, μετάDELETE, μετά σε ακολουθία ζευγώνFETCH/STOREγια να μετατοπίσει τα υπόλοιπα στοιχεία κάτω, και μετάSTORESIZE. Ένας προσαρμοσμένος χειριστήςSHIFTσχεδόν πάντα αξίζει να γραφεί για επιδόσεις.Αναφορές πινάκων: η
shift @$arefκαι ηshift @{ $expr }λειτουργούν και οι δύο. Ηshift $aref(χωρίς το sigil@) ήταν πειραματικό χαρακτηριστικό που προστέθηκε στην Perl 5.14 και αφαιρέθηκε στην 5.24 - είναι συντακτικό σφάλμα στην έκδοση Perl που στοχεύει η pperl.Η
shiftείναι καταναλωτής-lvalue, όχι lvalue: δεν μπορείτε να αναθέσετε στο αποτέλεσμα τηςshiftγια να τροποποιήσετε τον πίνακα. Χρησιμοποιήστεspliceή απευθείας ανάθεση με δείκτη για αυτό.Τιμή επιστροφής σε περιβάλλον λίστας: η
shiftεπιστρέφει πάντα ένα μονό βαθμωτό. Η ανάθεση του αποτελέσματός της σε λίστα -my ($x) = shift @arr- λειτουργεί μόνο επειδή το μονό βαθμωτό γεμίζει την πρώτη θέση λίστας· οι υπόλοιπες θέσεις είναιundef. Χρησιμοποιήστεspliceγια να αφαιρέσετε πολλά στοιχεία ταυτόχρονα.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
pop- αφαιρεί και επιστρέφει το τελευταίο στοιχείο· O(1), η σωστή επιλογή όταν δεν χρειάζεται διάταξη FIFOpush- προσαρτά στην ουρά· ζευγαρωμένη με τηνshiftσχηματίζει ουρά FIFOunshift- προσθέτει στην κεφαλή· η αντίστροφη τηςshift, και επίσης O(n) για τον ίδιο λόγοsplice- αφαιρεί, εισάγει, ή αντικαθιστά οποιαδήποτε συνεχόμενη ακολουθία στοιχείων· το γενικό εργαλείο όταν δεν αρκούν οιshift/pop/unshift/push@ARGV- ο προεπιλεγμένος πίνακας τον οποίο καταναλώνει ηshiftσε εμβέλεια αρχείου@_- ο προεπιλεγμένος πίνακας τον οποίο καταναλώνει ηshiftμέσα σε sub· κρατά τη λίστα ορισμάτων του καλούντος