Τριαδικός τελεστής#
Ένας τελεστής, τρεις τελεστέοι. Λογική επιλογή ως έκφραση - το αποτέλεσμα έχει τιμή, μπορεί να ανατεθεί, να επιστραφεί, να μεταβιβαστεί ως όρισμα.
Μορφή#
COND ? THEN : ELSE
Αν η COND είναι αληθής, η τιμή είναι THEN· αλλιώς είναι ELSE. Μόνο ο επιλεγμένος κλάδος αποτιμάται:
my $label = $count == 1 ? "1 item" : "$count items";
return $ok ? \%result : undef;
my $abs = $x < 0 ? -$x : $x;
Είναι έκφραση, όχι δήλωση#
Ο πιο συνηθισμένος λόγος να χρησιμοποιήσετε ?: αντί για if/else είναι ότι θέλετε μια τιμή - για ανάθεση, για επιστροφή, για τοποθέτηση μέσα σε μια άλλη έκφραση:
# verbose
my $kind;
if ($n == 1) { $kind = 'singular' }
else { $kind = 'plural' }
# idiomatic
my $kind = $n == 1 ? 'singular' : 'plural';
Αλυσίδωση (δεξιά προσεταιριστική)#
Η A ? B : C ? D : E αναλύεται ως A ? B : (C ? D : E) - η αλυσίδα κατεβαίνει μέσω του ψευδούς κλάδου:
my $sign = $x < 0 ? '-'
: $x > 0 ? '+'
: '0';
Η διάταξη σε στήλες κάνει την αλυσίδα αναγνώσιμη. Μετά από δύο ή τρία επίπεδα, αλλάξτε σε if/elsif/else - η αλυσίδα παύει να είναι πιο σαφής από την εναλλακτική.
Τριαδικός ως lvalue#
Και οι δύο κλάδοι πρέπει να είναι lvalues, και ο επιλεγμένος κλάδος είναι το lvalue στο οποίο γίνεται ανάθεση:
my ($pos, $neg) = (0, 0);
($x > 0 ? $pos : $neg) = $x; # assigns to $pos or $neg
# Common case: pick a buffer to append to
($verbose ? $log : $debug) .= "$msg\n";
Αυτό το μοτίβο είναι σπάνιο σε σύγχρονο κώδικα - ένα ρητό if με δύο ευθείες αναθέσεις διαβάζεται καλύτερα. Αξίζει να το γνωρίζετε για όταν το συναντήσετε.
Τι δεν γράφετε#
Ο ?: δεν είναι διαχωριστής δηλώσεων. Αυτά είναι λάθος:
$x ? do_a() : do_b(); # OK: do_a/do_b have side-effects,
# but the value is discarded
$x > 0 ? print "yes\n" : print "no\n"; # WORKS, but reads strangely
Όταν ο στόχος είναι μια παρενέργεια (αντί για τιμή), χρησιμοποιήστε if/else ή το μεταθεματικό if/unless:
$x > 0 ? do_yes() : do_no(); # value-return phrasing
do_yes() if $x > 0; # side-effect phrasing
do_no() unless $x > 0;
Με λογικούς τελεστές βραχυκυκλώματος#
Ο ?: αλληλεπιδρά με &&, ||, // με τρόπους που μπορούν να μπερδέψουν το μάτι. Σχεδόν πάντα βάζετε παρενθέσεις:
my $x = $a || $b ? $c : $d; # parses as ($a || $b) ? $c : $d
# because || binds tighter than ?:
my $x = $a || ($b ? $c : $d); # if you meant the other thing,
# parenthesise
Προτεραιότητα#
Ο ?: βρίσκεται στη γραμμή 18 - χαλαρότερος από τους λογικούς τελεστές (&&/||///), σφιχτότερος από την ανάθεση. Γι” αυτό η my $x = COND ? A : B λειτουργεί χωρίς παρενθέσεις γύρω από τη δεξιά πλευρά.
Δείτε επίσης#
Logical - βραχυκύκλωμα
&&και||, η οικογένεια εναλλακτικής χωρίςif.-
?:in the context of all the boolean operators.
Assignment - ο
?:ως lvalue.