Na przykład, wolisz ten jednowarstwowy
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
lub rozwiązanie if / else obejmujące wiele instrukcji zwrotu?
Kiedy jest to ?:
właściwe, a kiedy nie? Czy należy go uczyć czy ukrywać przed początkującymi?
operators
conditions
FredOverflow
źródło
źródło
Odpowiedzi:
Nie, to błogosławieństwo.
Gdy jest to coś tak prostego, że nie chcesz marnować wielu linii.
Gdy cierpi czytelność i przejrzystość kodu, a prawdopodobieństwo błędu z powodu niewystarczającej uwagi wzrasta, na przykład, w przypadku wielu operatorów łańcuchowych, tak jak w twoim przykładzie.
Test lakmusowy ma miejsce, gdy zaczynasz wątpić, czy Twój kod jest łatwy do odczytania i utrzymania na dłuższą metę. Więc nie rób tego.
źródło
myVar = someExpression ? false : true;
(someExpression ? var1 : var2)++
:-)Myślę, że nieskrócony operator trójskładnikowy (tj. Instrukcja, w której jest używany tylko raz) jest w porządku, ale jeśli zagnieżdżasz więcej niż jeden, staje się on nieco trudny do odczytania.
źródło
Kiedy jest?: Odpowiednie
a kiedy nie jest?
Jeśli masz jakieś wywołania logiczne lub funkcyjne w wyrażeniu potrójnym, to sprawia, że patrzenie na nie jest okropne.
źródło
Jedną z różnic, których (jak sądzę) nikt nie zauważył, jest to, że jeśli-inaczej nie może zwrócić wartości, podczas gdy operator potrójny może.
Pochodząc z F #, czasami lubię używać trójskładnikowego operatora do naśladowania dopasowania wzorca.
vs
źródło
var res = function() {switch(input) {case 1: return "1"; case 2: return "2"; ...}}()
emulowanie przełączników jako wyrażeń.expression
istatement
zawsze się martwię, że źle je zrozumiem i zrobię z siebie głupka :)const
zmiennych, których później nie można zmienić.Przykład (IMHO) prawidłowego użycia:
Powoduje to, że kod jest bardziej czytelny niż posiadanie 2 różnych instrukcji drukowania. Zagnieżdżone przykłady zależą: (zrozumiałe? Tak: nie)
źródło
Absolutnie nie zło. W rzeczywistości jest czysty , a jeśli tak, to nie jest.
W językach funkcjonalnych, takich jak Haskell, F #, ML itp., To stwierdzenia typu „jeśli to inaczej” są uważane za złe.
Powodem tego jest to, że każda „akcja”, taka jak bezwzględna instrukcja if-then-else, wymaga oddzielenia deklaracji zmiennej od jej definicji i wprowadza stan do funkcji.
Na przykład w następującym kodzie:
vs.
Pierwszy ma dwie zalety oprócz tego, że jest krótszy:
x
jest stały, a zatem oferuje znacznie mniejszą szansę na wprowadzenie błędów i może zostać zoptymalizowany w sposób, w jaki drugi nigdy nie mógłby być.x
musi on być typuParity
.Mylące jest to, że w językach funkcjonalnych operator trójskładnikowy jest często nazywany „jeśli-to”. W Haskell można powiedzieć
x = if n mod 3 == 1 then Odd else Even
.źródło
Ten szczególny wyraz sprawia, że bolą mnie oczy; Zwalczę dowolnego programistę w moim zespole, który go użył, ponieważ jest nie do utrzymania.
Operatory trójskładnikowe nie są złe, gdy są dobrze stosowane. Nie muszą nawet być pojedynczymi liniami; Długi, dobrze sformatowany, może być bardzo jasny i łatwy do zrozumienia:
Podoba mi się to bardziej niż ekwiwalent łańcucha if / then / else:
Przeformatuję je w:
jeśli warunki i zadania pozwalają na łatwe wyrównanie. Nadal wolę wersję trójskładnikową, ponieważ jest krótsza i nie ma tak dużo hałasu wokół warunków i zadań.
źródło
ReSharper w VS.NET czasami sugeruje zastąpienie
if...else
go?:
operatorem.Wydaje się, że ReSharper sugeruje tylko wtedy, gdy warunki / bloki są poniżej pewnego poziomu złożoności, w przeciwnym razie będzie się trzymać
if...else
.źródło
Można to przeformatować, aby wyglądało tak ładnie, jak kombinacja if / else:
Problem polega jednak na tym, że nie jestem do końca pewien, czy dostałem prawo do wgłębienia do przedstawienia tego, co się naprawdę wydarzy. :-)
źródło
if-else
struktura. Kluczem jest formatowanie.Potrójny operator nie jest złem, ale jest darem niebios.
Jest to najbardziej przydatne, gdy chcesz podjąć decyzję w wyrażeniu zagnieżdżonym . Klasycznym przykładem jest wywołanie funkcji:
W twoim konkretnym przykładzie trójka jest prawie nieuzasadniona, ponieważ jest wyrażeniem najwyższego poziomu w
return
. Możesz podnieść warunek do poziomu instrukcji, nie powielając niczego innego niżreturn
słowo kluczowe.Uwaga: Nic nigdy nie sprawi, że ten konkretny algorytm mediany będzie łatwy do odczytania.
źródło
printf("I see %d evil construct%s in this program\n", n, "s" unless (n == 1) "s");
Pomijając argumenty „zła”, z mojego doświadczenia wynika, że istnieje duża korelacja między użytkowaniem przez programistę operatora trójskładnikowego a prawdopodobieństwem, że cała jego baza kodowa będzie trudna do odczytania, śledzenia i utrzymywania (jeśli nie wręcz nieudokumentowana). Jeśli programista jest bardziej zainteresowany zapisaniem kilku linii 1-2 znaków niż ktoś, kto jest w stanie zrozumieć jego kod, wówczas wszelkie drobne nieporozumienia związane ze zrozumieniem trójki są zazwyczaj wierzchołkiem góry lodowej.
Trójskładnikowi przyciągają magiczne liczby, takie jak s ** t przyciąga muchy.
Gdybym szukał biblioteki Open Source, aby rozwiązać konkretny problem, i zobaczyłem kod, taki jak trójskładnikowi oryginalnego plakatu, kandydata na tę bibliotekę, dzwonki ostrzegawcze zaczęłyby bić mi w głowie i zastanowić się nad przejściem do jakiegoś innego projektu, z którego można pożyczyć.
źródło
Oto przykład, kiedy jest zły:
Jest to mylące i marnotrawstwo. Kompilator może zoptymalizować drugie wyrażenie (oldValue = oldValue), ale dlaczego programista zrobił to w pierwszej kolejności?
Kolejny doozy:
Niektórzy ludzie nie są po prostu programistami ...
Greg twierdzi, że odpowiednik instrukcji if jest „głośny”. Jest tak, jeśli piszesz to głośno. Ale to samo, jeśli można zapisać jako:
Który nie jest głośniejszy niż trójskładnikowy. Zastanawiam się, czy trójskładnikowe skróty; czy wszystkie wyrażenia są oceniane?
źródło
if (x != 0) x = 0;
...Zło? Spójrz, są po prostu inne.
if
jest stwierdzeniem.(test ? a : b)
jest wyrażeniem. To nie to samo.Istnieją wyrażenia, które wyrażają wartości. Istnieją instrukcje do wykonywania działań. Wyrażenia mogą pojawiać się w instrukcjach, ale nie odwrotnie. Możesz więc używać wyrażeń potrójnych w innych wyrażeniach, takich jak terminy w podsumowaniu lub argumenty metody, i tak dalej. Nie musisz , ale możesz, jeśli chcesz . Nie ma w tym nic złego. Niektórzy ludzie mogą powiedzieć, że to zło, ale taka jest ich opinia.
Jedną z wartości wyrażenia potrójnego jest to, że pozwala ci obsługiwać zarówno przypadki prawdziwe, jak i fałszywe.
if
oświadczenia nie.Jeśli martwisz się o czytelność, możesz sformatować je w czytelny sposób.
Jakoś „zło” wkradło się do słownictwa programistycznego. Chciałbym wiedzieć, kto pierwszy to upuścił. (Właściwie mam podejrzanego - on jest w MIT.) Wolałbym mieć obiektywne powody, by oceniać wartości w tej dziedzinie, a nie tylko gust i imię ludzi.
źródło
Ma miejsce. Pracowałem w wielu firmach, w których poziomy umiejętności programistów wahają się od strasznych do czarodziei. Ponieważ kod musi być utrzymany, a ja nie będę tam na zawsze, staram się pisać rzeczy tak, aby wyglądały, jakby do nich należały (bez patrzenia na komentarze z moimi inicjałami, jest niezwykle rzadkie, abyś mógł spójrz na kod, nad którym pracowałem, aby zobaczyć, gdzie wprowadziłem zmiany) i że ktoś z mniejszymi umiejętnościami niż ja może go utrzymać.
Podczas gdy operator trójskładnikowy wygląda niesamowicie i jest całkiem fajny, z mojego doświadczenia wynika, że linia kodu będzie niemożliwa do utrzymania. U mojego obecnego pracodawcy mamy produkty, które są wysyłane od prawie 20 lat. Nigdzie nie użyłbym tego przykładu.
źródło
Nie sądzę, aby operator potrójny był zły.
Oto gotcha, która mnie zaskoczyła. Byłem programistą C dla wielu (10+) i pod koniec lat 90. przeszedłem do programowania aplikacji internetowych. Jako programista internetowy wkrótce natknąłem się na PHP, który ma również trójskładnikowego operatora. Miałem błąd w programie PHP, który w końcu prześledziłem do linii kodu za pomocą zagnieżdżonego operatora trójskładnikowego. Okazuje się, że operator trójskładnikowy PHP jest skojarzony od lewej do prawej, ale operator trójskładnikowy C (do którego byłem przyzwyczajony) kojarzy od prawej do lewej.
źródło
Wszystko, co czyni brzydszy kod, jest złe.
Jeśli używasz trójskładnikowego, aby twój kod był czystszy, z pewnością go użyj. Czasami w php świetnie jest robić wbudowane podstawienia, np
To oszczędza kilka linii i jest całkiem jasne, ale twój przykład wymaga co najmniej lepszego formatowania, aby był wyraźny, a trójskładnik nie jest tak naprawdę dobry dla wielu linii, to równie dobrze możesz użyć if / else.
źródło
Czy mogę to powiedzieć? Nie mogę znaleźć tego konkretnego zastosowania potrójnej operacji zła :
Proszę, zmiłuj się, moja reputacja jest już dość żałosna.
źródło
Największa wygrana: pokazanie, że istnieje jeden cel działania.
Istnieją dwie ścieżki kodu, którymi można podążać, a czytelnik musi uważnie przeczytać, aby sprawdzić, które dwie zmienne są ustawiane. W tym przypadku jest to tylko jedna zmienna, ale czytnik musi przeczytać więcej, aby to zrozumieć. W końcu mogło być tak:
Dzięki operatorowi trójskładnikowemu jest jasne, że ustawiana jest tylko jedna zmienna.
Na najniższym poziomie zasada DRY (Don't Repeat Yourself) jest najbardziej podstawowa. Jeśli możesz podać
$foo
tylko raz, zrób to.źródło
Jeśli ... to ... inaczej kładzie nacisk na warunek i dlatego nie uwypukla operacji wykonywanych warunkowo.
operator trójskładnikowy jest przeciwny, ma tendencję do ukrywania warunku i dlatego jest użyteczny, gdy wykonywana operacja jest ważniejsza niż sam warunek.
W niektórych językach istnieje niewielki problem techniczny, polegający na tym, że nie są one do końca wymienne, ponieważ jedno jest instrukcją, a drugie wyrażeniem, np. Warunkowo inicjuje const w C ++
źródło
Myślę, że przy opracowywaniu dla jednorodnej grupy ludzi nie ma problemu, ale kiedy masz do czynienia z osobami, które obsługują różne poziomy, ten rodzaj onelinerów wprowadza tylko dodatkowy poziom złożoności do kodu. Tak więc moja polityka w tej sprawie jest następująca: kod wyczyść i nie wyjaśniaj zamiast kodu krótkiego i wyjaśnij 123123 razy.
Nie powinienem być uczony początkującym, raczej wybieraj go, aby zrozumiał, kiedy pojawi się potrzeba, więc będzie używany tylko wtedy, gdy będzie to konieczne, a nie za każdym razem, gdy będziesz potrzebować „if”.
źródło
IMO, sam operator nie jest zły, ale składnia zastosowana w C (i C ++) jest zbyt zwięzła. IMO, Algol 60 zrobił to lepiej, więc coś takiego:
wyglądałby mniej więcej tak (ale ogólnie trzymając się składni podobnej do C):
Nawet przy tym nadmiernie głębokie zagnieżdżanie może prowadzić do problemów z czytelnością, ale przynajmniej A) każdy, kto w ogóle wykonał programowanie, może rozwiązać ten problem, a B) ludzie, którzy go rozumieją, radzą sobie z znacznie głębszym zagnieżdżaniem. OTOH, chciałbym również zauważyć, że w LISP (na przykład) a
cond
jest prawie jak instrukcja trójskładnikowa - nie zestaw instrukcji, ale pojedyncze wyrażenie daje wartość (wtedy znowu większość LISP jest taka ... .)źródło
A = (x==y) ? B : C
Sklep, który regularnie pisze metody o numerach 600-1200, nie powinien mi mówić, że trójka jest „trudna do zrozumienia”. Żaden sklep, który regularnie dopuszcza pięć warunków do oceny gałęzi kodu, nie powinien mi powiedzieć, że konkretnie podsumowane warunki w trójce są „trudne do odczytania”.
źródło
Kiedy jest: odpowiednie, a kiedy nie?
Czy należy go uczyć czy ukrywać przed początkującymi?
To nie ma znaczenia, ale nie powinno być celowo ukryte, ponieważ nie jest zbyt skomplikowane, aby „początkujący” mógł się uczyć.
źródło
W twoim przykładzie:
jest bardzo prosty do odczytania i oczywisty. Zmienna pomiędzy <<to wartość zwracana.
Aktualizacja
to samo, ale mniej wierszy kodu. Myślę, że nadal jest prosty.
źródło
Jest to również konieczne dla const
źródło
const
tak myślę w niektórych językach. W C #const
zawsze powinna być znana wartość czasu kompilacji. co oznacza, żeconst int nLegs = isChicken ? 2: 4 ;
nie zadziała, aleconst int nLegs = true ? 2: 4 ;
będzie