Bash ' operator condiționat și atribuire

Putem folosi operatorul condițional bash cu operatori de atribuire după colon?

Manual de referință Bash explică operatorii aritmetici după cum urmează.

  • operator condiționat expr ? expr : expr
  • atribuire = *= /= %= += -= <<= >>= &= ^= |=

În primul rând, acest cod pare să funcționeze bine:

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

Dar când folosesc operatori de atribuire după :, am primit o eroare de „încercare de atribuire la variabilă”:

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

De ce putem folosi numai operatori de atribuire înainte de colon?

Comentarii

  • Poate fi amuzant să efectuați atribuții variabile folosind operatorul condițional, dar ' face codul dvs. foarte ilizibil. I ' prefer ((a)) && b=1 || c=1
  • @devnull Cred că codul depinde cel mai mult de cine o citește. Totuși, poate fi adevărat ceea ce spuneți, dar am ' testat ternary operatori în dash, zsh, sh și bash și se comportă la fel, în ciuda faptului că nu au fost specificate de POSIX. Exemplul dvs. funcționează numai în bash și zsh din câte știu. Cu toate acestea, acesta este prietenos cu POSIX: ( : ${a?} ) && b=1 || c=1. De asemenea, mi se pare mult mai ușor de citit decât ternary sau propriul exemplu.

Răspuns

Bash analizează ultima comandă ca

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

care ar trebui să clarifice de ce nu funcționează. În schimb, trebuie să utilizați

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

Răspuns

Aceasta se numește ternary assignment expresie. Iată „un pic dintr-un alt răspuns al meu:

% 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 

Vedeți, după cum spuneți, aceasta este o operațiune de atribuire condițională . Depinde de condiții. Sintaxa funcționează astfel:

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

Nu cred că o folosești corect.

De la wikipedia :

?: după cum urmează:

condition ? value_if_true : value_if_false

Condiția este evaluată adevărată sau falsă ca expresie booleană. Pe baza evaluării condiției booleene, întreaga expresie returnează value_if_true dacă condiția este adevărată, dar value_if_false altfel. De obicei, cele două sub-expresii value_if_true și value_if_false trebuie să aibă același tip, care determină tipul întregii expresii. Importanța acestei verificări de tip constă în cea mai obișnuită utilizare a operatorului – în instrucțiunile de atribuire condiționată. În această utilizare apare ca o expresie în partea dreaptă a unei instrucțiuni de atribuire, după cum urmează:

variable = condition ? value_if_true : value_if_false

?: operatorul este similar cu modul în care expresiile condiționale (if-then-else construiesc) funcționează în limbaje funcționale de programare, cum ar fi Scheme, ML și Haskell, deoarece if-then-else formează un expresie în loc de o afirmație în aceste limbi.

Cred că problema dvs. specifică este legată de aceasta:

La fel ca în construcția if-else se evaluează doar una dintre expresiile „x” și „y”.

Dacă citiți linkul de mai sus pe expresiile ternary vei vedea acea evaluare n este scurtcircuitat, deci atribuirea dvs. pe false erori laterale deoarece 1 = true.

În orice caz, nu contează prea mult pentru că nu cred că acest lucru face ceea ce crezi că face.

Răspuns

Operatorii ternari returnează o valoare bazată pe un test. Nu sunt utilizate pentru ramificare.

Iată o modalitate de a obține un operator pseudo-ternar pentru bash (rețineți căpușele):

$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

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *