Operator warunkowy Bash ' i przypisanie

Czy możemy użyć operatora warunkowego basha z operatorami przypisania po dwukropku?

Bash podręcznik referencyjny wyjaśnia następujące operatory arytmetyczne.

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

Po pierwsze, ten kod wydaje się działać dobrze:

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

Ale kiedy używam operatorów przypisania po :, otrzymałem błąd „próbowano przypisać do wartości innej niż zmienna”:

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

Dlaczego przed dwukropkiem możemy używać tylko operatorów przypisania?

Komentarze

  • Wykonywanie przypisań zmiennych za pomocą operatora warunkowego może być zabawne, ale ' sprawi, że kod będzie wysoce nieczytelny. ' wolę ((a)) && b=1 || c=1
  • @devnull Myślę, że kod ' czytelność zależy głównie od tego, kto czyta. Mimo wszystko może być prawdą, co mówisz, ale ' przetestowałem ternary operatory w dash, zsh, sh i bash i wszystkie zachowują się tak samo, mimo że nie są określone przez POSIX. Twój przykład działa tylko w bash i zsh, o ile wiem. Jest to jednak zgodne z POSIX: ( : ${a?} ) && b=1 || c=1. Uważam też, że jest o wiele łatwiejszy do odczytania niż ternary lub własny przykład.

Odpowiedź

Bash analizuje Twoje ostatnie polecenie jako

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

, co powinno wyjaśnić, dlaczego nie działa. Zamiast tego musisz użyć

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

Answer

To się nazywa ternary assignment wyrażenie. Oto fragment z innej mojej odpowiedzi:

% 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 

Jak mówisz, jest to operacja przypisania warunkowego . To zależy od warunków. Składnia wygląda następująco:

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

Nie sądzę, że używasz tego poprawnie.

Od wikipedia :

?: jest używany w następujący sposób:

condition ? value_if_true : value_if_false

Warunek jest oceniany jako prawda lub fałsz jako wyrażenie boolowskie. Na podstawie oceny warunku logicznego całe wyrażenie zwraca wartość_jeżeli_prawda, jeśli warunek jest prawdziwy, ale wartość_jeśli_fałsz w przeciwnym razie. Zwykle dwa wyrażenia podrzędne wartość_jeżeli_prawda i wartość_jeżeli_fałsz muszą mieć ten sam typ, który określa typ całego wyrażenia. Znaczenie tego sprawdzania typu leży w najczęstszym zastosowaniu operatora – w warunkowych instrukcjach przypisania. W tym przypadku pojawia się jako wyrażenie po prawej stronie instrukcji przypisania, w następujący sposób:

variable = condition ? value_if_true : value_if_false

?: jest podobny do sposobu, w jaki wyrażenia warunkowe (konstrukcje if-then-else) działają w funkcjonalnych językach programowania, takich jak Scheme, ML i Haskell, ponieważ if-then-else tworzy wyrażenie zamiast instrukcji w tych językach.

Myślę, że twój konkretny problem jest związany z tym:

Tak jak w konstrukcji if-else tylko jedno z wyrażeń „x” i „y” jest oceniane.

Jeśli przeczytasz powyższy link na temat wyrażeń ternary zobaczysz tę ocenę n jest zwarte, więc twoje przypisanie po fałszywej stronie błędów, ponieważ 1 = true.

W każdym razie nie ma to znaczenia za dużo, ponieważ nie sądzę, że działa to tak, jak myślisz.

Odpowiedź

Operatory trójskładnikowe zwracają wartość na podstawie Badanie. Nie są używane do rozgałęziania.

Oto jeden ze sposobów uzyskania pseudo-potrójnego operatora dla bash (zwróć uwagę na znaki wstecz):

$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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *