Bash ' s betingede operator og tildeling

Kan vi bruge bashs betingede operator med tildelingsoperatorer efter kolon?

Bash-referencehåndbog forklarer aritmetiske operatorer som følger.

  • betinget operator expr ? expr : expr
  • tildeling = *= /= %= += -= <<= >>= &= ^= |=

Først ser denne kode ud til at fungere godt:

a=1; ((a? b=1 : 2 )) #seems to work 

Men når jeg bruger tildelingsoperatører efter :, fik jeg “forsøgt at tildele til ikke-variabel” -fejl:

a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error 

Hvorfor kan vi kun bruge tildelingsoperatorer før kolon?

Kommentarer

  • Det kan være sjovt at udføre variable tildelinger ved hjælp af den betingede operator, men det ' d gør din kode yderst uleselig. Jeg ' Jeg foretrækker ((a)) && b=1 || c=1
  • @devnull Jeg tror koden ' s læsbarhed afhænger mest af, hvem der læser den. Det kan stadig være sandt, hvad du siger, men jeg ' har testet ternary operatører i dash, zsh, sh og bash, og de opfører sig alle ens, til trods for at de ikke er specificeret af POSIX. Dit eksempel fungerer kun i bash og zsh så vidt jeg ved. Dette er dog POSIX-venligt: ( : ${a?} ) && b=1 || c=1. Jeg finder det også meget lettere at læse end enten ternary eller dit eget eksempel.

Svar

Bash analyserer din sidste kommando som

a=1; (( (a? b=1 : c)=1 )) 

, hvilket skulle gøre det klart, hvorfor det ikke fungerer. I stedet skal du bruge

a=1; (( a? b=1 : (c=1) )) 

Svar

Dette kaldes en ternary assignment udtryk. Her “er lidt fra et andet af mine svar:

% a=abc % b=abcd % t=10 ; f=5 % echo $((r=${#a}>${#b}?t:f)) ; echo $r > 5 > 5 % echo $((r=${#a}<${#b}?t:f)) ; echo $r > 10 > 10 

Du kan se, som du siger, dette er en betinget tildelingshandling. Det afhænger af forholdene. Syntaksen fungerer således:

$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign )) 

Jeg tror ikke, du bruger dette korrekt.

Fra wikipedia :

?: som følger:

condition ? value_if_true : value_if_false

Betingelsen evalueres som sand eller falsk som et boolsk udtryk. På basis af evalueringen af den boolske tilstand returnerer hele udtrykket værdi_om_ sandt, hvis betingelsen er sand, men ellers værdi_om_falsk. Normalt skal de to underudtryk value_if_true og value_if_false have samme type, der bestemmer typen for hele udtrykket. Vigtigheden af denne typekontrol ligger i operatørens mest almindelige anvendelse – i betingede tildelingserklæringer. I denne brug vises det som et udtryk i højre side af en opgaveerklæring som følger:

variable = condition ? value_if_true : value_if_false

?: -operatøren ligner den måde, hvorpå betingede udtryk (if-then-else -konstruktioner) fungerer i funktionelle programmeringssprog, som Scheme, ML og Haskell, da if-then-else danner en udtryk i stedet for en erklæring på disse sprog.

Jeg tror, at dit specifikke problem er relateret til dette:

Som i if-else-konstruktionen evalueres kun et af udtrykkene “x” og “y”.

Hvis du læser gennem ovenstående link på ternary udtryk du vil se den evaluering n er kortsluttet, så din opgave på falske sidefejlene, fordi 1 = true.

Under alle omstændigheder betyder det ikke noget for meget, fordi jeg ikke tror, det gør, hvad du synes, det gør.

Svar

Ternære operatører returnerer en værdi baseret på en test. De bruges ikke til forgrening.

Her er en måde at få en pseudo-ternær operatør til bash (bemærk back-ticks):

$result=`[ < condition > ] && echo "true-result" || echo "false-result" `

$ a= $ c=`[ $a ] && echo 1 || echo 0` $ echo $c 0 $ a=5 $ c=`[ $a ] && echo 1 || echo 0` $ echo $c 1

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *