Czy nawiasy klamrowe powinny pojawiać się na własnej linii? [Zamknięte]


273

Czy nawiasy klamrowe powinny być na własnej linii, czy nie? Co o tym myślisz?

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

a może powinno być

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

lub nawet

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

Bądź konstruktywny! Wyjaśnij dlaczego, dziel się doświadczeniami, poprzyj je faktami i referencjami.


104
Uważam, że „== true” jest bardziej rozpraszające niż wybór ustawienia nawiasów klamrowych.
Dan Dyer,

11
@Dan: Myślę, że zawsze wyjaśnianie wyrażenia warunkowego bardzo pomaga w jasności.
Wizard79

4
Jedyny powód, dla którego miałoby to znaczenie, to fakt, że IDE / edytor nie obsługuje dopasowywania rozpoznawania nawiasów klamrowych.
leeand00

4
@ leeand00: niektórzy z nas nadal drukują złożony / nieznany kod, aby go przestudiować / opatrzyć adnotacjami. Dobra ładna drukarka łagodzi większość problemów.
Shog9

2
smutne pytanie jest zamknięte. Po pewnym czasie użycia składni opartej na wcięciach zmieniłem (może dziwnie) inną strukturę nawiasów klamrowych. Jak twój pierwszy, ale zamykający nawias klamrowy w ostatniej linii bloku. (po wierszu kodu)
cnd

Odpowiedzi:


88

Kiedy byłem studentem, umieszczałem nawiasy klamrowe w tym samym wierszu, aby było mniej wierszy, a kod był drukowany na mniejszej liczbie stron. Patrzenie na pojedynczy nawias drukowany jako jedyną rzecz w linii jest denerwujące. (środowisko, marnotrawstwo papieru)

Ale przy kodowaniu dużych aplikacji, dopuszczenie niektórych linii zawierających tylko nawiasy klamrowe jest przystępne, biorąc pod uwagę wrażenie grupowania.

Niezależnie od tego, który styl wybierzesz, zachowaj spójność, aby Twój mózg nie przetwarzał wielu stylów w powiązanych fragmentach kodu . W różnych scenariuszach (jak wyżej) powiedziałbym, że można używać różnych stylów, łatwiej jest „przełączać kontekst” na wysokim poziomie.


6
Z drugiej strony klamrą nowej linii jest ANSI STANDARD, a K&R nie. Ale piękno w standardach polega na tym, że istnieje tak wiele różnych (patrz także uncyclopedia.wikia.com/wiki/AAAAAAAA ! Na uncyclopedia).
Quandary

„jest mniej linii” Mam terabajty przestrzeni i dużo pikseli. Dlaczego mam się przejmować używaniem większej liczby linii?
12431234123412341234123

1
@ 12431234123412341234123: Myślę, że ma na myśli, ponieważ niektóre osoby drukują kod w celu przejrzenia kodu. I każda niekoniecznie nowa linia jest marnowana na papier, lub km² forrestu marnowany na dużą skalę. Jednak jeśli go nie wydrukujesz (a ja na pewno nie), ANSI jest o wiele lepszy niż K&R. Ponadto każdy, kto zamierza drukować, powinien prawdopodobnie skorzystać ze zautomatyzowanego formatyzatora kodu - więc powinno to być kwestia narzędzi, a nie stylu kodowania.
Quandary

247

Nigdy nie powinieneś robić trzeciej metody.

Przeskakiwanie na nawiasach klamrowych może zaoszczędzić ci kilku naciśnięć klawiszy za pierwszym razem, ale następny koder, który pojawia się, dodaje coś do twojej klauzuli else, nie zauważając, że w bloku brakuje nawiasów klamrowych.

Napisz swój kod dla innych osób.


113
Chciałbym wiedzieć, skąd pochodzi ta odrobina mądrości. Ponieważ pisanie kodu dla osób, które nie zawracają sobie głowy jego czytaniem, jest tak bezcelowe, jak to tylko możliwe ...
Shog9

69
Drugi programista może dodawać własne nawiasy klamrowe, gdy coś dodaje. Nie jest głupi, a w konwencji kodowania, która zachęca do pomijania nawiasów klamrowych dla takich prostych rzeczy, będzie wiedział.
Ken Bloom

25
Opcjonalne nawiasy klamrowe nie są opcjonalne. Istnieje kilka gorszych decyzji projektowych, które zostały podjęte w C i przeniesione na jego potomków. To, że żyje w języku tak nowym jak C #, wywołuje u mnie gniew.
Adam Crossland

28
Nie ma znaczenia, jak mądry jesteś i jak zakorzeniony jest standard kodowania wokół pojedynczych pomijanych curlies: jeśli szukasz rozwiązania problemu lub błędu, prawdopodobnie przegapisz pomijanie curlies. A czy przy tak długich 2 sekundach pracy, tak naprawdę tak źle jest mówić wprost?
Jordan

11
Jest jedna zaleta stylu nr 3, której wszyscy wszyscy brakuje: naraz dostajesz więcej kodu na ekranie.
Loren Pechtel,

203

Przez długi czas twierdziłem, że są one jednakowej wartości lub tak bardzo bliskie równości, że możliwy zysk dzięki dokonaniu właściwego wyboru był znacznie, znacznie niższy niż koszt kłótni o to.

Będąc zgodny jest ważna , choć. Więc powiedziałem, rzućmy monetą i zacznijmy pisać kod.

Widziałem już wcześniej, że programiści nie chcą się tak zmieniać. Pokonaj to! Zmieniałem się wiele razy w mojej karierze. Używam nawet różnych stylów w moim C # niż w PowerShell.

Kilka lat temu pracowałem nad zespołem (~ 20 programistów), który postanowił poprosić o dane wejściowe, a następnie podjąć decyzję, a następnie egzekwować ją w całej bazie kodu. Będziemy mieli tydzień na podjęcie decyzji.

Dużo jęków i przewracających oczami. Wiele „Lubię swoją drogę, bo jest lepiej”, ale bez substancji.

Gdy badaliśmy drobne szczegóły pytania, ktoś zapytał, jak poradzić sobie z tym problemem w stylu brace-on-the-the-line:

void MyFunction(
    int parameterOne,
    int parameterTwo) {
    int localOne,
    int localTwo
}

Zauważ, że nie jest od razu oczywiste, gdzie kończy się lista parametrów, a zaczyna ciało. Porównać do:

void MyFunction(
    int parameterOne,
    int parameterTwo) 
{
    int localOne,
    int localTwo
}

Przeczytaliśmy, jak ludzie na całym świecie poradzili sobie z tym problemem, i znaleźliśmy wzór dodawania pustej linii po otwartym nawiasie:

void MyFunction(
    int parameterOne,
    int parameterTwo) {

    int localOne,
    int localTwo
}

Jeśli zamierzasz zrobić wizualną przerwę, równie dobrze możesz to zrobić za pomocą klamry. Wtedy twoje wizualne przerwy również stają się spójne.

Edycja : Dwie alternatywy dla rozwiązania „dodatkowej pustej linii” podczas korzystania z K&R:

1 / Wcięcie argumentów funkcji inaczej niż w treści funkcji

2 / Umieść pierwszy argument w tym samym wierszu co nazwa funkcji i dopasuj kolejne argumenty w nowych wierszach do tego pierwszego argumentu

Przykłady:

1 /

void MyFunction(
        int parameterOne,
        int parameterTwo) {
    int localOne,
    int localTwo
}

2 /

void MyFunction(int parameterOne,
                int parameterTwo) {
    int localOne,
    int localTwo
}

/Edytować

Nadal twierdzę, że spójność jest ważniejsza niż inne względy, ale jeśli nie mamy ustalonego precedensu , to właściwym rozwiązaniem jest brace-on-next-line.


33
FYI, może brzmieć jak rozsądna osoba, ale w rzeczywistości jestem wariatem. W przypadku prostych bloków jednowierszowych nie będę używać nawiasów klamrowych ani znaków nowej linii, tworząc „if (foo) bar ()” wszystkie jedną linię. Staram się, aby mój kod był tak prosty, że nie stanowi problemu.
Jay Bazuzi,

38
Przyszedł tutaj, aby opublikować dokładnie to. Mnóstwo ludzi, którzy trzymają nawias otwierający w tej samej linii, podążają za nim pustą linią (szczególnie na początku klas i metod), ponieważ inaczej trudno jest oddzielić nagłówek klasy / metody od ciała. Cóż, jeśli i tak zamierzasz użyć dodatkowej linii, równie dobrze możesz umieścić tam klamrę i uzyskać dodatkową korzyść w postaci wcięcia, która jest łatwiejsza do zobaczenia.
Jewgienij Brikman

27
Nie widziałem pustej linii - lepiej znam podwójne wcięcie parametrów MyFunction (), gdy zbaczają do innej linii.
Armand

34
Rozbijanie parametrów na wiele takich linii jest denerwujące.
Fosco,

10
Argument „parametru funkcji” to czerwony śledź. Oczywiście argumenty powinny być podwójnie zamierzone. Nie ma problemu, aby odróżnić go od następującego kodu.
David Ongaro

99

Główne zasady to:

  1. Postępuj zgodnie z istniejącym standardem kodowania projektu.
  2. Jeśli nie ma standardu kodowania i edytujesz istniejącą bazę kodu należącą do kogoś innego - zachowaj spójność ze stylem istniejącego kodu, bez względu na to, jak bardzo go lubisz.
  3. Jeśli pracujesz nad projektem typu green-field - dyskutuj z innymi członkami zespołu i osiągnij konsensus w sprawie formalnego lub nieformalnego standardu kodowania.
  4. Jeśli pracujesz nad projektem typu green-field jako jedyny programista - podejmij decyzję, a następnie bądź bezwzględnie konsekwentny.

Nawet jeśli nie masz żadnych zewnętrznych ograniczeń, najlepiej (IMO) poszukać istniejącego (powszechnie używanego) standardu kodowania lub wytycznych dotyczących stylu i spróbować tego przestrzegać. Jeśli rzucisz własny styl, istnieje duża szansa, że ​​za kilka lat będziesz żałować.

Wreszcie styl, który jest implementowany / możliwy do wdrożenia przy użyciu istniejących kontrolerów stylów i formatatorów kodu, jest lepszy niż styl, który należy „wymusić” ręcznie.


10
Ta odpowiedź zasługuje na więcej głosów.
AShelly

1
spójność jest kluczowa
MediaVince

70

Zaletą pierwszej metody jest to, że jest bardziej kompaktowa w pionie, dzięki czemu można zmieścić więcej kodu na ekranie i dlatego wolę. Jedynym argumentem, który usłyszałem na korzyść drugiej metody, jest to, że ułatwia ona parowanie nawiasów otwierających i zamykających, ale większość IDE ma do tego skrót klawiaturowy, a tak naprawdę jest to fałszywa instrukcja - zamiast parowania nawiasów otwierających z zamykającym nawias możesz sparować nawias zamykający z wyrażeniem „początek bloku” (jeśli, inaczej, przez chwilę) na tym samym poziomie wcięcia, więc równie łatwo jest ustalić, gdzie jest początek bloku.

Nie widzę powodu, aby marnować całą linię tylko na nawias, gdy poprzednia konstrukcja for / while / if już wizualnie wskazuje początek bloku.

To powiedziawszy, uważam, że nawias zamykający powinien znajdować się we własnej linii, ponieważ potrzebujemy czegoś, co wskazywałoby koniec bloku i jego strukturę wcięcia w widoczny sposób.


12
Nie ... Mówię, dlaczego zmniejszać ilość kodu, która może zmieścić się na ekranie, robiąc coś, co nie zwiększa przejrzystości kodu?
EpsilonVector,

6
Kiedy zaczynałem kodować, podoba mi się każdy nawias klamrowy na osobnej linii, teraz wolę pierwszą metodę
NimChimpsky

57
Istnieje wiele badań, sięgających wczesnej epoki Steam (Weinberg, „Psychology of Computer Programming”), które pokazują, że rozumienie programisty spada DRAMATYCZNIE, gdy ilość kodu, który należy obejrzeć, jest większa niż może być widocznym za jednym razem (tj. jeden ekran, jedna strona drukarki). Zjawisko to przemawia MOCNIE w postrzeganiu przestrzeni pionowej jako cennego zasobu, którego nie można zmarnować bezinteresownie, dlatego też preferowana jest pierwsza metoda.
John R. Strohm,

10
LOL @ „marnowanie CAŁEJ linii”. O MÓJ BOŻE! Nie to!! = P
Nick Spreitzer,

6
@Julio Na studiach zdecydowanie preferowałem metodę 1 i nie mogłem znieść czytania metody 2. Po przejściu do pracy w firmie używającej C #, gdzie standardem jest metoda 2, polubiłem ją również. Mogę teraz czytać lub używać albo; nikt mi nie przeszkadza. Ludzie, którzy mają bardzo niechętną reakcję na jedną lub drugą, generalnie przesadzają z czymś, czego nie znają.
KChaloux,

46

wolę

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

koniec

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

ponieważ wiersz you.postAnswer();jest znacznie łatwiejszy do odczytania i znalezienia na pierwszy rzut oka. Po drugie, wtapia się w linię powyżej ( you.hasAnswer()), przez co moje oczy muszą bardziej skupić się na czytaniu.


7
Dzieje się tak, dopóki twój program nie przekroczy wysokości ekranu. ;)
weberc2

13
@ weberc2 Myślę, że kiedy twój program przekroczy wysokość ekranu, dwie linie mniej nie zmienią się zbytnio.
Mageek

13
10 lat temu zgodziłbym się na miejsce na ekranie. Dzisiaj używam ekranu 1920 * 1200. Pasuje do WIELU kodów, więcej niż mój mózg może przetworzyć naraz. Pierwsza metoda pozwala mi cofnąć się i zobaczyć inne otwieranie / zamykanie lunety bez konieczności czytania.
LightStriker

3
Nigdy nie mogłem zrozumieć, dlaczego wolałem tę metodę, ale właśnie po to.
Declan McKenna

2
@Mageek To jest spóźnione, ale to nie są 2 linie, to 2 linie dla każdego zakresu. To O (N), a nie O (1). Tak naprawdę nie czuję się tak mocno; ważniejsze jest wybranie stylu, który sprawia, że ​​długie listy parametrów są czytelne.
weberc2

38

Wolę pierwszą metodę. Nawiasy klamrowe nie są warte oddzielnej linii.

Chodzi o to, że nawiasy klamrowe nie są ważne. Są tylko śmieciami składniowymi , które są absolutnie niepotrzebne do zrozumienia, do czego służy kod, jego celu i sposobu jego implementacji. Są tylko hołdem dla języków w starym stylu C, w których wizualne grupowanie operatorów było niemożliwe ze względu na mało dostępnego miejsca na ekranie.

Są języki (Python, Haskell, Ruby), które są w porządku bez nawiasów klamrowych. To tylko potwierdza, że ​​nawiasy klamrowe są śmieci i nie powinny zasłużyć na linię, jeśli to możliwe:

if (you.hasAnswer()){
    you.postAnswer();
}else{
    you.doSomething();
}

7
Nie wiem o Haskell ani Ruby, ale Python jest wrażliwy na białe znaki, dlatego nie wymaga nawiasów klamrowych ani innych ograniczników do oznaczania bloków. Szelki to nie tylko hałas syntaktyczny; służą rzeczywistemu celowi.
Robert Harvey

14
@Robert, w C musisz zrobić zarówno białe znaki, jak i nawiasy klamrowe. W Pythonie powinieneś robić tylko białe znaki. Który jest lepszy?
P Shved

5
@Pavel, w C 'nie musisz robić białych znaków.
Ken Bloom

7
Programy @KenBloom C bez białych znaków są niemożliwe do odczytania. Więc i tak musisz to zrobić.
P Shved

6
Niezależnie od tego, czy nawiasy klamrowe są dobrym pomysłem, czy nie, samo istnienie języków, które ich nie używają, nie wydaje się argumentem za lub przeciw nim. Sugeruje jedynie, że można mieć język bez nich, a nie, że jest to dobry lub zły projekt języka.
Jason

37

Użyj Pythona i całkowicie pomiń argument.


17
+1SyntaxError: not a chance
Seth

6
Nie jest to po prostu opcja dla ogromnej większości projektów. Dodatkowo, wcięcie dla grupowania ma wiele problemów.
Bryan Oakley

@Bryan, zdaję sobie sprawę, że nie jest to zbyt praktyczne. Pomyślałem, że to punkt widzenia, który musi tam być, silniejszy niż tylko komentarz. I nigdy nie napotkałem problemów spowodowanych wcięciem, które sugerujesz, prawdopodobnie dlatego, że nie mieszam tabulatorów i spacji.
Mark Ransom

Użyj Go i całkowicie ominąć argument (plus wpisywanie statyczne, szybkość i kompilator!) :)
weberc2

4
Następnie naciśnij klawisz spacji zbyt wiele razy i obserwuj, jak kompilator / tłumacz śmieje się z ciebie. Nie zdarzy się to w większości języków.
Pharap

27

Pozycja nawiasów klamrowych powinna być

metadane

konfigurowalny w IDE przez programistę. W ten sposób te nieznośne nawiasy klamrowe w całym kodzie, niezależnie od autora, wyglądają tak samo.


7
Kompletnie się zgadzam. To prezentacja, a nie dane.
Petruza

Problem polega na tym, że jeśli pozwolisz wszystkim ustawić własne, bardzo szybko robi się bałagan po zakończeniu zatwierdzania.
Andy

1
@Andy: Właśnie o to chodzi, IDE zmieni wygląd, ale tylko w IDE! Rzeczywiste źródło nie zostanie zmienione. W celu kontroli wersji można dodawać zaczepy, które tłumaczą dowolne ustawienie nawiasów klamrowych do typowej sytuacji, dzięki czemu wszyscy sprawdzają kod w ten sam sposób.
klaar

@klaar Każde używane przeze mnie IDE zmieni tabulatory na spacje i przeniesie nawiasy klamrowe do własnej linii lub końca linii „otwierającej”; Nie jestem pewien, dlaczego uważasz, że źródło nie zostało zmienione w tych przypadkach, i to jest powód mojego komentarza. Zazwyczaj jest to zmieniane przez IDE w zależności od ustawień programistów, co oznacza, że ​​podczas zatwierdzenia zobaczę wiele zmian, które są tylko szumem, gdy nawiasy przesuną się do własnej linii, ukrywając w ten sposób RZECZYWISTĄ zmianę, którą ktoś zrobił.
Andy

@Andy: Czy nie ma możliwości użycia haczyków, które przekształcają te rozbieżności dotyczące białych znaków i nawiasów klamrowych w jednolity standard po zatwierdzeniu, aby obejść opisany przez ciebie problem z hałasem? Tak czy inaczej, odpowiedni system wersjonowania powinien wykraczać poza drobiazgi, takie jak białe znaki lub inne nonsensowne rzeczy.
klaar

19

To zależy.

Jeśli piszę w JavaScript lub jQuery, używam pierwszej formy:

jQuery(function($) { 
    if ($ instanceOf jQuery) { 
        alert("$ is the jQuery object!"); 
    } 
}); 

Ale jeśli koduję w C #, używam drugiej formy, ponieważ jest to kanoniczny sposób, aby to zrobić w C #.

public int CalculateAge(DateTime birthDate, DateTime now) 
{ 
    int age = now.Year - birthDate.Year; 
    if (now.Month < birthDate.Month 
        || (now.Month == birthDate.Month && now.Day < birthDate.Day)) 
        age--; 
    return age; 
} 

Pamiętaj, że twój przykład można napisać

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

w C #.


1
Można go napisać w wielu takich językach, ponieważ instrukcja blokowa jest instrukcją. Dodawanie! :-)
Tamara Wijsman,

2
Zgodnie z „Wytycznymi dotyczącymi projektowania ram” „kanonicznym sposobem” jest umieszczenie otwierającego nawiasu klamrowego w tej samej linii (tj. W pierwszej formie). Tylko
mówię

3
@Uwe: Być może. Ale Microsoft zastosował podejście „wyrównane nawiasy klamrowe” dla wszystkich swoich przykładów MSDN C # i jest wypiekany do Visual Studio, więc ...
Robert Harvey

@Uwe: To książka Cwaliny i jest strasznie nazwana, ponieważ jest czymś więcej. FDG na MSDN nie ma nic do powiedzenia na ten temat. Zastanawiam się także, dlaczego wytyczne projektowania ramowego miałyby cokolwiek mówić o praktyce kodowania C # ?
R. Martinho Fernandes

3
W rzeczywistości powinieneś umieścić nawiasy klamrowe w tej samej linii w Javascript. Możesz powodować błędy, jeśli nawiasy klamrowe znajdują się na swojej linii. Na przykład patrz encosia.com/…
Joseph Hansen

18

Wolę pierwszy, ponieważ trudniej mi dostrzec błąd w tym przykładzie.

if (value > maximum);
{
    dosomething();
}

niż w tym przykładzie

if (value > maximum); {
    dosomething();
}

Po ; {prostu wygląda mi bardziej źle niż linia kończąca się, ;więc bardziej prawdopodobne jest, że to zauważę.


11
Robisz dobry argument, ale osobiście to zdarzyło mi się tylko raz podczas mojego 5-letniego programowania. Nie mogłem zrozumieć, dlaczego się nie uruchamia, opublikowałem to na SO i ktoś szybko wskazał mi średnik. Jednak za każdym razem, gdy skrócone jest użycie tej 1 linii mniejszej, trudniej jest mi ją przeczytać.
JD Isaacks

6
„; {” Wygląda jak mrugająca zrzędliwa twarz lub osoba z wąsami.
glenatron,

+1 Świetny przykład w odpowiedzi: bardzo subtelny błąd, łatwo przeoczony. Myśl prowokująca również w układzie pokazującym to.
therobyouknow

10
Oczywiście każde przyzwoite IDE oflaguje pustą instrukcję sterowania, a każdy przyzwoity kompilator wyda ostrzeżenie.
Dunk

@Dunk Jedyną wadą twojego argumentu (z którym zdecydowanie się zgadzam) jest to, że tak wielu ludzi używa obecnie interpretowanych języków (JavaScript, PHP, i inni), że wielu „programistów” nie znałoby kompilatora latte.
Craig,

15

Wolę niewielki wariant 1)

if (you.hasAnswer()) {
    you.postAnswer();
} // note the break here
else {
    you.doSomething();
}

Dlaczego?

  • Myślę zawsze umieszczanie nawiasów klamrowych na ich własnej linii zmniejsza czytelność. Mogę zmieścić tylko pewną ilość kodu źródłowego na ekranie. Styl wspornika 2) sprawia, że ​​algorytmy podnoszenia z wieloma zagnieżdżonymi pętlami i warunkami są boleśnie długie.

  • Chcę elsejednak zacząć od nowej linii, ponieważ ifielse wizualnie należą do siebie. Jeśli przed nim znajduje się wspornik else, znacznie trudniej jest dostrzec, co należy do czego.

  • 3) dyskwalifikuje się. Wszyscy wiemy, co złego może się stać, jeśli pominiesz nawiasy i zapomnisz o tym.


1
Widziałem ten, w którym pracuję. To interesujące.
Almo

1
Ten styl też mi się bardziej podoba, ponieważ pozwala mi w elserazie potrzeby umieszczać komentarz nad linią i / lub wstawiać pustą linię między blokiem if i blokiem else, aby rzeczy wyglądały mniej zatłoczone. Styl nawiasu klamrowego nr 2 robi jedynie odsuwanie akcji od warunków. Z powiedział, że moim ulubionym jest zdecydowanie Pythona nie styl wspornik :)
sayap

4
Jeśli ważne jest maksymalne zwiększenie liczby linii kodu na ekranie, po prostu całkowicie zrezygnuj z nowych linii. Będziesz mógł uzyskać wiele linii na jednym ekranie. Wolę, aby nic nie zmuszało mnie do pauzy i myślenia podczas czytania, tj. moja definicja bardziej czytelna. Z aparatami ortodontycznymi mój umysł je ignoruje. Bez aparatów ortodontycznych mój umysł musi zatrzymać się i wyrównać bloki kontrolne. Nie długa pauza, ale pauza mimo wszystko.
Dunk

1
Tak, jeśli i jeszcze należą do siebie, ALE tak też {i} i ponieważ} jest w osobnej linii, {też powinien być w osobnej linii. „Mogę zmieścić tylko pewną ilość kodu źródłowego na moim ekranie” I właśnie dlatego powiedzenie 3) byłoby „dyskwalifikacją samego siebie” nie jest żadną opcją. Po dekadzie pracy z 3) nigdy nie zapomniałem dodawać nawiasów podczas dodawania nowej linii kodu, ani nie znam nikogo, kto kiedykolwiek miał. Jeśli muszę dostosować kod do osób, które nie potrafią poprawnie odczytać, gdzie to się kończy? Przestajesz używać niektórych funkcji językowych, ponieważ niektóre czytniki kodów mogą ich nie rozumieć?
Kaiserludi

10

Czytałem gdzieś, że autorzy niektórych książek chcą, aby ich kod był sformatowany w następujący sposób:

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

Ale ograniczenia przestrzenne ze strony wydawcy oznaczały, że musieli użyć tego:

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

Teraz nie wiem, czy to prawda (ponieważ nie mogę jej już znaleźć), ale ten drugi styl jest bardzo rozpowszechniony w książkach.

Osobiście wolę nawiasy w osobnej linii, ponieważ:

a) wskazują nowy zakres,
b) łatwiej jest wykryć niedopasowanie (choć jest to mniejszy problem w środowisku IDE, który podkreśla błędy).


... Druga opcja ułatwia także oba punkty (z samym wcięciem służącym do kombinacji nawiasów klamrowych / wcięcia). :)
weberc2

10

Ach, styl One True Brace .

Ma wszystko, czego potrzeba Świętej Drodze - nawet proroka (Richard „moja droga lub autostrada” Stallman).

Facet tak bardzo mylił się co do tak wielu rzeczy, ale GNU jest znakomita, jeśli chodzi o aparaty ortodontyczne.


[Aktualizacja] Widziałem światło i teraz czczę Allmana


9
Nie widzę sensu stylu GNU, poza modelowaniem kodu lisp. Wydaje się, że dużo pracy przynosi niewielkie korzyści.
Robert Harvey

Nie znam nikogo, kto używa stylu GNU. 1 TB do końca.
Jé Queue

Nie można zrobić nic gorszego niż dwa poziomy wcięcia na blok, z wyjątkiem stylu seplenia, co oczywiście jest oczywiste.
ergosys

4
+1 za link dotyczący stylów klamr. To pokazuje, że bez względu na twój styl, wielu wspaniałych ludzi nie zgadza się z tobą.
Florian F

@RobertHarvey Nie ma dodatkowej pracy, jeśli tak, nie używasz odpowiedniego narzędzia do pisania kodu ani nie konfigurujesz go poprawnie. Korzyścią jest znacznie bardziej czytelny kod, każdy błąd w nawiasie widać bardzo szybko i można łatwo odczytać tylko kod z ignorując podbloki.
12431234123412341234123

9

Drugi przykład, jestem bardzo duży w zakresie czytelności. Nie mogę znieść patrzenia na bloki w jakikolwiek inny sposób = (


1
Badania wskazują, że łatwiej jest odczytać zwarty kod, gdy podstawa kodu przekroczy wysokość ekranu.
weberc2

5
@ weberc2, czy mógłbyś dostarczyć DOI do tych prac badawczych?
Grzegorz Adam Kowalski

9

Prosta odpowiedź: co łatwiej debugować?

// Case 1:
void dummyFunction() {
  for (i = 0; i != 10; ++i) {
    if (i <= 10)
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there";
  }
} // COMPILER ERROR HERE


// Case 2:
void dummyFunction()
{
  for (i = 0; i != 10; ++i)

    if (i <= 10)
    {
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there\n";
  }
} // COMPILER ERROR HERE

W którym przypadku zdiagnozowałeś problem najpierw?

Nie dbam o osobiste preferencje (istnieje wiele innych stylów, w tym biali i inni) i nie obchodzi mnie to zbyt długo ... dopóki nie utrudni to mojej umiejętności czytania kodu i debugowania go.

Co do argumentu „marnuj miejsce”, nie kupuję go: i tak dodam puste linie między grupami logicznymi, aby program był bardziej przejrzysty ...


1
Oba są równie łatwe do debugowania, głównie dlatego, że jest to krótki blok kodu. Wcięcie jest spójne, co ułatwia wizualizację rzeczywistych bloków kodu.
Htbaa

@Htbaa: rzeczywiście :) Więc po co zawracać sobie głowę?
Matthieu M.

@MatthieuM. Pierwszy blok ma dla mnie większy sens, ponieważ nowe linie (w drugim bloku) między sygnaturą funkcji, instrukcją for i instrukcją if sprawiają, że uważam, że nie są ze sobą powiązane, ale najwyraźniej tak nie jest. Puste linie oddzielają niepowiązane bity kodu; kod zbliżony do innych wierszy kodu oznacza, że ​​są one faktycznie powiązane. To wszystko oczywiście „imo”, ale zastanawiałem się, o co ci chodzi. EDYCJA: również każde właściwe IDE zauważy brak nawiasu klamrowego i da ci odrobinę błędów podczas interpretacji twojego kodu.
klaar

7

Nie żeby ktokolwiek to zauważył, ale właśnie dlatego nawiasy klamrowe należą do tej samej linii co warunek (z wyjątkiem bardzo długich warunków warunkowych, ale to przypadek na krawędzi):

W C jest to poprawna konstrukcja:

while (prawda);
{
    char c;
    getchar (); // Poczekaj na dane wejściowe
}

Szybki! Co robi ten kod? Jeśli odpowiedziałeś „nieskończona pętla z pytaniem o dane wejściowe”, jesteś w błędzie! Nawet nie dostaje się do wejścia. Zostaje złapany na while(true). Zauważ, że średnik na końcu. Ten wzór jest w rzeczywistości bardziej powszechny, niż się wydaje; C wymaga od ciebie zadeklarowania zmiennych na początku bloku, dlatego właśnie uruchomiono nową.

Linia kodu to myśl. Nawiasy klamrowe są częścią myśli zawierającej warunkową lub pętlę. Dlatego należą do tej samej linii.


To zdecydowanie najlepszy argument dla stylu K&R, jaki widziałem, reszta jest śmieszna z dzisiejszych systemów IDE z obsługą składania kodu. Dotyczy to tylko języków w stylu C, które obsługują ;zakończenia bloków. Dlatego też nienawidzę tego systemu zakończenia bloku, którego IMHO jest przestarzały, a język Go to potwierdza. Widziałem ten problem wiele razy, chociaż nie w tym scenariuszu. Zwykle dzieje się tak, gdy zamierzają dodać coś do oświadczenia i zapomnieć.
Jeremy

5

Lubię pierwszą metodę. Wydaje się ładniejszy IMO i jest bardziej kompaktowy, co lubię.

EDYCJA: Ach, trzeci. Najbardziej podoba mi się ten, gdy jest to możliwe, ponieważ jest jeszcze mniejszy / schludniejszy.


5

Możesz to napisać:

you.hasAnswer() ? you.postAnswer() : you.doSomething();

Aby odpowiedzieć na pytanie; Kiedyś wolałem nawiasy klamrowe na ich własnej linii, ale aby uniknąć konieczności myślenia o błędach spowodowanych automatycznym wstawianiem średników w przeglądarkach, zacząłem używać stylu egipskiego do javascript. A kiedy kodowałem Javę w zaćmieniu, nie byłem zainteresowany walką (lub konfigurowaniem) domyślnego stylu nawiasów klamrowych, więc w tym przypadku poszedłem również do Egiptu. Teraz mam wszystko jedno i drugie.


do użycia w ten sposób postAnswer()i doSomething()powinien zwrócić wartość dla operatora trójskładnikowego, co często nie jest prawdą: mogą bardzo dobrze zwrócić wartość void (bez wartości). a także (przynajmniej w c #) wynik ?:należy przypisać do jakiejś zmiennej
ASh

4

Prawie wszystkie odpowiedzi tutaj mówią pewną odmianę „Cokolwiek robisz, trzymaj się jednego lub dwóch”.

Pomyślałem o tym przez chwilę i musiałem przyznać, że nie uważam tego za tak ważne. Czy ktoś może mi szczerze powiedzieć, że trudno jest przestrzegać następujących zasad?

int foo(int a, Bar b) {
    int c = 0;
    while(a != c)
    {
        if(b.value[a] == c) {
            c = CONST_A;
        }
        c++;
    }
    return c;
}

Nie jestem pewien, czy ktokolwiek inny ... ale mam absolutnie zerowe problemy z mentalnym przełączaniem się między stylami. Zajęło mi kilka chwil, aby dowiedzieć się, co zrobił kod, ale to wynik mojego losowego wpisywania składni podobnej do C. :)

Moim niezbyt skromnym zdaniem otwieranie nawiasów jest prawie całkowicie nieistotne dla czytelności kodu. Istnieje kilka przypadków narożnych wymienionych powyżej, w których jeden styl ma znaczenie, ale w większości rozsądne użycie pustych linii usuwa to.

FWIW, nasze style kodowania w pracy używają nieco bardziej uporządkowanej postaci 1 i zmodyfikowanej postaci 3. (C ++)

            // blank line is required here
if (x) {
            //This blank line is required
   y = z;
}
            // blank line is required here too, unless this line is only another '}'

if (x) y = z; //allowed

if (x)
    y = z;  // forbidden

Jestem ciekawy, czy ci, którzy zdecydowanie wolą formę 2, polubiliby tę wersję formy 1 tylko dlatego, że pusta linia zapewnia silniejszą separację wizualną.


4
Jak pokazuje twój przykład, wcięcie jest tak samo ważne jak nawiasy klamrowe dla czytelnego kodu. W rzeczywistości niektóre języki sprawiają, że wcięcie jest jedynym sposobem zagnieżdżania instrukcji!

1
Ok, szczerze mówiąc, uważam cię za niespójny przykład trudny do odczytania. Nie NAPRAWDĘ trudne, ale trudniejsze niż gdyby były spójne.
Almo

Zgadzam się z Almo. To nie jest przypadek „czy to naprawdę trudne”. Jest to przypadek „jest zdecydowanie trudniejszy”, nawet jeśli nie trudny. Dlaczego więc utrudniać? W przykładach „zabawkowych”, które ludzie podają, oczywiście różnica jest niewielka. Z mojego doświadczenia wynika, że ​​kiedy dziedziczę nieprzyjemny kod od kogoś innego, który używał metody 1, dość często konieczne jest przejście do metody 2, aby móc podążać za logiką. Ponieważ często staje się to konieczne; automatycznie odpowiada na pytanie, która metoda jest lepsza i łatwiejsza do zrozumienia.
Dunk

@Dunk: Nie mogę pojąć kodu, który zostałby zauważalnie ulepszony poprzez zamianę tak mało istotnych szczegółów.
jkerian

@ jkerian-Najwyraźniej nie odziedziczyłeś dużo kodu od innych, którzy odeszli z projektu lub firmy. Nie mogę pojąć, że nikt nie miałby takiej sytuacji przez kilka lat. Ale z drugiej strony sytuacja pracy każdego jest inna. Ponadto, jeśli trzeba wykonać „formalne” przeglądy kodu, formatowanie robi spore różnice. Bardzo ważna jest umiejętność czytania kodu w sposób naturalny. Jasne, że mogę zatrzymać się i pomyśleć o dopasowaniu nawiasów klamrowych, ale to spowalnia proces. Jeden sposób nie wymaga pauzy, inne wymagają. Dlatego nie rozumiem, dlaczego można zalecić jakikolwiek inny wybór.
Dunk

4

Dziwię się, że to jeszcze nie zostało podniesione. Wolę drugie podejście, ponieważ pozwala ono łatwiej wybrać blok.

Kiedy nawiasy klamrowe zaczynają się i kończą w tej samej kolumnie i we własnej linii, możesz wybierać z marginesu lub za pomocą kursora w kolumnie 0. Zasadniczo oznacza to bardziej obszerny obszar z wyborem myszy lub mniejszą liczbę naciśnięć klawiszy z wyborem klawiatury.

Początkowo pracowałem z nawiasami klamrowymi na tej samej linii co warunek, ale po zmianie zauważyłem, że przyspieszyłem tempo, z jakim pracowałem. Oczywiście nie jest to noc i dzień, ale coś, co nieco spowolni pracę z aparatami ortodontycznymi przy stanach warunkowych.


Stare zegary, takie jak ja, używają trzech naciśnięć klawiszy, aby wybrać blok bez względu na to, gdzie są te cholerne klamry.
ergosys

2

Osobiście lubię drugi sposób.

Jednak sposób, w jaki zamierzam to zademonstrować, jest moim zdaniem najlepszy, ponieważ zapewnia największe bezpieczeństwo pracy! Kolega z mojego uniwersytetu poprosił mnie o pomoc w odrabianiu lekcji i tak wyglądał jego kod. Cały program wyglądał jak pojedynczy blok. Interesujące jest to, że 95% błędów w programie, który stworzył, pochodzi z niedopasowanych aparatów ortodontycznych. Pozostałe 5% było oczywiste po dopasowaniu nawiasów klamrowych.

while(1){
i=0;
printf("Enter coded text:\n");
while((s=getchar())!='\n'){
         if(i%1==0){
            start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!");
exit(1);}
input=start;}
      input[i++]=s;}
start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!!!");
exit(1);}
input=start;
input[i]='\0';
                puts(input);

8
Zły, zły, mam na myśli straszny, okropny przykład. Problemem nie są szelki! To szalone wcięcie!
R. Martinho Fernandes

@Martinho Fernandes Myślałem, że umieszczanie nawiasów klamrowych i wcięcia idą w parze ...
AndrejaKo

2
niekoniecznie ... wykonaj odpowiednie wcięcie w powyższym, a następnie losowo przełączaj style nawiasów klamrowych, przekonasz się, że jest to zrozumiałe.
jkerian

W rzeczywistości myślenie o tym zmotywowało moją własną odpowiedź na to pytanie.
jkerian

„95% błędów w programie, który popełnił, pochodziło z niedopasowanych nawiasów klamrowych” - tylko w interpretowanych językach, nieskompilowanych.
Mawg

2

Moje osobiste preferencje dotyczą pierwszej metody, prawdopodobnie dlatego, że tak właśnie nauczyłem się PHP.

W przypadku ifinstrukcji jednowierszowych użyję

if (you.hasAnswer()) you.postAnswer();

Jeśli to nie jest, you.postAnswer();ale coś znacznie dłuższego, na przykład you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType);prawdopodobnie powrócę do pierwszego typu:

if (you.hasAnswer) {
    you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType);
}

Nigdy nie użyję podziału linii i nigdy nie użyję tej metody, jeśli istnieje także elseinstrukcja.

if (you.hasAnswer()) you.postAnswer();
else you.doSomething()

jest teoretyczną możliwością, ale nie taką, której bym kiedykolwiek użył. Trzeba to zmienić

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

2

Oni nie powinni; pierwsza metoda dla mnie.

Kiedy patrzę na drugi, ze względu na nieużywane linie (te, które mają tylko nawiasy klamrowe, inne niż ostatnia nawias zamykający), mam wrażenie, że przerywa ciągłość kodu. Nie mogę go odczytać tak szybko, ponieważ muszę zwrócić szczególną uwagę na puste wiersze, które zwykle oznaczają rozdzielenie celu kodu lub coś takiego, ale w żadnym wypadku „ta linia należy do nawiasów klamrowych” (co tylko powtarza znaczenie wcięcia).

W każdym razie, podobnie jak podczas pisania tekstu ... dodawanie wcięcia na początku akapitu jest zbędne, jeśli przed nim jest pusta linia (podwójny znak zmiany akapitu), nie ma potrzeby marnować linii na nawiasy klamrowe, gdy jesteśmy prawidłowe wcięcie.

Ponadto, jak już wspomniano, pozwala zmieścić więcej kodu na ekranie, co w przeciwnym razie jest nieco przeciwne do zamierzonego.


2

To zależy od platformy / języka / konwencji

W Javie:

void someMethod() { 
     if (you.hasAnswer()) {
         you.postAnswer();
     } else {
       you.doSomething();
     }
}

W C #

void someMethod() 
{ 
     if (you.hasAnswer()) 
     {
         you.postAnswer();
     } 
     else 
     {
       you.doSomething();
     }
}

W C:

void someMethod() 
{ 
     if (you_hasAnswer()) {
         you.postAnswer();
     } else {
       you_doSomething();
     }
}

Nienawidzę, kiedy faceci Java używają swojego stylu w kodzie C # i vice versa.


3
Styl C zawsze mnie denerwował. Bądź konsekwentny!
Christian Mann,

1

Wszystko, co mogę powiedzieć, to to, że jeśli jesteś fanem metody nr 3, będziesz prześladowany przez każdy program formatujący kod IDE na ziemi.


1

Pierwszej metody używam po prostu dlatego, że jest bardziej zwarta i pozwala na więcej kodu na ekranie. Sam nigdy nie miałem problemu ze sparowaniem nawiasów klamrowych (zawsze wypisuję je wraz z ifinstrukcją przed dodaniem warunku, a większość środowisk pozwala przeskoczyć do pasującego nawiasu klamrowego).

Jeśli nie trzeba powiązać się szelki wizualnie, to wolałbym drugą metodę. Pozwala to jednak na zmniejszenie liczby kodów jednocześnie, co wymaga przewijania większej liczby. I to, przynajmniej dla mnie, ma większy wpływ na odczytywanie kodu niż posiadanie starannie dopasowanych nawiasów klamrowych. Nienawidzę przewijania. Z drugiej strony, jeśli chcesz przewinąć jedną ifinstrukcję, najprawdopodobniej jest ona zbyt duża i wymaga refaktoryzacji.

Ale; najważniejsza jest konsekwencja. Użyj jednego lub drugiego - nigdy obu!


0

Kiedy uczyłem się programowania w wieku 12 lat, umieściłem nawiasy klamrowe w następnym wierszu, ponieważ takie są samouczki na temat kodowania Microsoft. W tym czasie naciąłem również 4-spacja TABS.

Po kilku latach nauczyłem się Java i JavaScript i widziałem więcej kodów nawiasów klamrowych na tej samej linii, więc zmieniłem się. Zacząłem również wciskać 2-spacjami.


5
+1, -1. Dlaczego NIE wcinasz tabulatorów, ponieważ każdy edytor może dopasować długość tabulatora do dowolnej długości? W przeciwnym razie przewodzisz wielu z nas, którzy lubią prawdziwe wcięcia w wieku 8 lat, aby przeklinać twój kod.
Jé Queue

0

Istnieje czwarta opcja, która utrzymuje nawiasy klamrowe w linii, ale nie marnuje miejsca:

if (you.hasAnswer())
{    you.postAnswer();
     i.readAnswer();
}
else
{   you.doSomething();
}

Jedyny problem polega na tym, że większość autoformaterów IDE dusi się na tym.


9
... podobnie jak większość programistów, którzy się na to dławili.
Jé Queue

4
To wydaje się przerażające. Pomyśl o dodatkowym wysiłku, który musisz wykonać, jeśli chcesz wstawić linię u góry lub usunąć górną linię. Nie możesz po prostu usunąć linii i przejść dalej, musisz pamiętać o ponownym wstawieniu nawiasu klamrowego.
Bryan Oakley,

lol to jest niesamowite! :) lepszy niż pierwszy styl!
nawfal

Najwyraźniej ma nawet nazwę. The Horstman Syyle jest wspomniany w Wikipedii . Pracowałem z taką bazą kodu, naprawdę nie jest źle używać.
AShelly,

-1

Wszystko zależy od ciebie, dopóki nie pracujesz nad projektem, w którym kierownik projektu określił pewne ograniczenia kodowania lub pewne standardy, które muszą przestrzegać wszyscy programiści pracujący nad tym projektem podczas kodowania.

Osobiście wolałbym pierwszą metodę.

Też nie dostałem tego, co chcesz pokazać trzecią metodą?

Czy to nie zły sposób? Na przykład rozważ sytuację jako ...

if (you.hasAnswer())
  you.postAnswer();
else
  you.doSomething();

Co teraz, jeśli ktoś chce dodać więcej instrukcji w bloku if ?

W takim przypadku, jeśli użyjesz trzeciej metody, kompilator zgłosi błąd składniowy.

if (you.hasAnswer())
   you.postAnswer1();
   you.postAnswer2();
else
   you.doSomething();

2
Jeszcze gorzej byłoby, gdyby ktoś przyszedł i zrobił: if (you.hasAnswer ()) you.postAnswer (); else you.doSomething (); you.doSomethingElse (); - to przepis na subtelne błędy, które można łatwo prześlizgnąć, a kompilator też nie pomoże
FinnNk

@FinnNk: Dokładnie!
Chankey Pathak,

2
Jeśli ktoś chce dodać kolejne oświadczenie, może sam włożyć nawiasy klamrowe. Każdy programista wart swojej soli naprawdę powinien to zrozumieć.
Robert Harvey

Chciałem powiedzieć, że jego trzecia metoda jest zła.
Chankey Pathak,

3
@Robert Harvey, widziałem, jak bardzo doświadczeni koderzy nie dodają nawiasów klamrowych podczas modyfikowania istniejącego kodu. Myślę, że problem polega na tym, że wcięcie jest znacznie silniejszą wskazówką co do znaczenia niż nawiasy klamrowe (zwłaszcza, że ​​istnieje wiele stylów nawiasów klamrowych), więc łatwo jest przeoczyć brakujący nawias klamrowy, jeśli wcięcie wygląda tak, jak się spodziewasz.
AShelly
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.