Kunnen we de voorwaardelijke operator van bash gebruiken met toewijzingsoperatoren na dubbele punt?
Bash-referentiehandleiding legt de rekenkundige operatoren als volgt uit.
- conditionele operator
expr ? expr : expr
- toewijzing
= *= /= %= += -= <<= >>= &= ^= |=
Ten eerste lijkt deze code goed te werken:
a=1; ((a? b=1 : 2 )) #seems to work
Maar als ik toewijzingsoperatoren gebruik na :
, kreeg ik een “poging tot toewijzing aan niet-variabele” fout:
a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error
Waarom kunnen we alleen toewijzingsoperatoren gebruiken vóór dubbele punt?
Opmerkingen
Antwoord
Bash parseert je laatste commando als
a=1; (( (a? b=1 : c)=1 ))
wat duidelijk zou moeten maken waarom het niet werkt. In plaats daarvan moet je
a=1; (( a? b=1 : (c=1) ))
Answer
gebruiken Dit wordt een ternary assignment
expressie. Hier “een stukje uit een ander antwoord van mij:
% 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
Je ziet, zoals je zegt, dit is een voorwaardelijke toewijzingsoperatie. Het hangt af van de voorwaarden. De syntaxis werkt als volgt:
$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign ))
Ik geloof niet dat u dit correct gebruikt.
Van wikipedia :
?:
wordt gebruikt als volgt:
condition ? value_if_true : value_if_false
De voorwaarde wordt als waar of onwaar geëvalueerd als een Booleaanse uitdrukking. Op basis van de evaluatie van de Booleaanse voorwaarde retourneert de volledige uitdrukking waarde_if_waar als voorwaarde waar is, maar waarde_als_waaraan anders. Gewoonlijk moeten de twee subuitdrukkingen value_if_true en value_if_false hetzelfde type hebben, wat het type van de hele uitdrukking bepaalt. Het belang van deze typecontrole ligt in het meest voorkomende gebruik van de operator – in voorwaardelijke toewijzingsinstructies. In dit gebruik verschijnt het als een uitdrukking aan de rechterkant van een toewijzingsinstructie, als volgt:
variable = condition ? value_if_true : value_if_false
De
?:
operator is vergelijkbaar met de manier waarop voorwaardelijke expressies (if-then-else
constructies) werken in functionele programmeertalen, zoals Scheme, ML en Haskell, aangezien if-then-else een expressie in plaats van een statement in die talen.
Ik denk dat uw specifieke probleem hiermee verband houdt:
Net als in de if-else-constructie wordt slechts één van de uitdrukkingen “x” en “y” geëvalueerd.
Als u de bovenstaande link leest op ternary
uitdrukkingen je zult die evaluatie zien n is kortgesloten, dus uw toewijzing aan de false -zijde fouten omdat 1 = true
.
In ieder geval maakt het niet uit te veel omdat ik niet denk dat dit doet wat je denkt dat het doet.
Answer
Ternaire operatoren retourneren een waarde gebaseerd op een toets. Ze worden niet gebruikt voor vertakkingen.
Hier is een manier om een pseudo-ternaire operator voor bash te krijgen (let op de 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
((a)) && b=1 || c=1
ternary
operators getest indash, zsh, sh
enbash
en ze gedragen zich allemaal hetzelfde, ondanks dat ze niet gespecificeerd zijn door POSIX. Uw voorbeeld werkt alleen inbash
enzsh
voor zover ik weet. Dit is echter POSIX-vriendelijk:( : ${a?} ) && b=1 || c=1
. Ik vind het ook veel gemakkelijker om te lezen danternary
of je eigen voorbeeld.