Τριαδικός τελεστής#

Ένας τελεστής, τρεις τελεστέοι. Λογική επιλογή ως έκφραση - το αποτέλεσμα έχει τιμή, μπορεί να ανατεθεί, να επιστραφεί, να μεταβιβαστεί ως όρισμα.

Μορφή#

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.

  • Boolean Logic - Operators

    • ?: in the context of all the boolean operators.

  • Assignment - ο ?: ως lvalue.