Bash ' s betingede operatør og oppgave

Kan vi bruke bashs betingede operatør med tildelingsoperatører etter kolon?

Bash-referansehåndbok forklarer aritmetiske operatorer som følger.

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

Først ser denne koden ut til å fungere bra:

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

Men når jeg bruker oppdragsoperatører etter :, fikk jeg «forsøkt tildeling til ikke-variabel» -feil:

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

Hvorfor kan vi bare bruke tildelingsoperatorer før kolon?

Kommentarer

  • Det kan være morsomt å utføre variable oppgaver ved hjelp av den betingede operatøren, men det ' d gjør koden din veldig uleselig. Jeg ' foretrekker ((a)) && b=1 || c=1
  • @devnull Jeg tror koden ' lesbarhet avhenger mest av hvem som leser den. Likevel kan det være sant det du sier, men jeg ' har testet ternary operatører i dash, zsh, sh, og bash og de oppfører seg alle like, til tross for at de ikke er spesifisert av POSIX. Eksemplet ditt fungerer bare i bash og zsh så vidt jeg vet. Dette er imidlertid POSIX-vennlig: ( : ${a?} ) && b=1 || c=1. Jeg synes det er også mye lettere å lese enn ternary eller ditt eget eksempel.

Svar

Bash analyserer den siste kommandoen din som

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

som skal gjøre det klart hvorfor det ikke fungerer. I stedet må du bruke

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

Svar

Dette kalles en ternary assignment uttrykk. Her «er litt fra et annet svar fra meg:

% 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 ser, som du sier, dette er en betinget tildelingsoperasjon. Det avhenger av forholdene. Syntaksen fungerer slik:

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

Jeg tror ikke du bruker dette riktig.

Fra wikipedia :

?: som følger:

condition ? value_if_true : value_if_false

Betingelsen blir vurdert som sant eller usant som et boolsk uttrykk. På grunnlag av evalueringen av den boolske tilstanden returnerer hele uttrykket value_if_true hvis condition er true, men value_if_false ellers. Vanligvis må de to underuttrykkene value_if_true og value_if_false ha samme type, som bestemmer typen for hele uttrykket. Betydningen av denne typekontrollen ligger i operatørens vanligste bruk – i betingede oppdragsuttalelser. I denne bruken vises det som et uttrykk på høyre side av en oppdragsuttalelse, som følger:

variable = condition ? value_if_true : value_if_false

?: operator ligner på måten betingede uttrykk (if-then-else konstruerer) fungerer i funksjonelle programmeringsspråk, som Scheme, ML og Haskell, siden if-then-else danner en uttrykk i stedet for en uttalelse på disse språkene.

Jeg tror det spesifikke problemet ditt er relatert til dette:

Som i if-else konstrueres bare ett av uttrykkene «x» og «y».

Hvis du leser gjennom lenken ovenfor på ternary uttrykk du ser den vurderingen n er kortsluttet, så oppgaven din på falske sidefeil fordi 1 = true.

I alle fall spiller det ingen rolle for mye fordi jeg ikke tror dette gjør det du tror det gjør.

Svar

Ternære operatører returnerer en verdi basert på en prøve. De brukes ikke til forgrening.

Her er en måte å få en pseudo-ternær operatør for bash (merk bakflåttene):

$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

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *