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
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
((a)) && b=1 || c=1
ternary
operatører idash, zsh, sh
, ogbash
og de oppfører seg alle like, til tross for at de ikke er spesifisert av POSIX. Eksemplet ditt fungerer bare ibash
ogzsh
så vidt jeg vet. Dette er imidlertid POSIX-vennlig:( : ${a?} ) && b=1 || c=1
. Jeg synes det er også mye lettere å lese ennternary
eller ditt eget eksempel.