Przerwanie nested for loops

Przerwanie nested for loops
SZ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1591
1
obscurity napisał(a):
WeiXiao napisał(a):

@obscurity

Wręcz przeciwnie, goto ma mniejszy narzut kognitywny, bo nie trzeba skakac i analizowac kilku funkcji

Przecież drugi przykład jest znacznie prostszy do przeanalizowania. Wiem że ciężko na przykładzie tak prostego kodu który się samemu napisało to odczuć ale w pierwszym przypadku widząc kod po raz pierwszy i natrafiając na etykietę musisz przerwać standardową analizę kodu i szukać wszystkich skoków. Jeszcze jak jest jedna etykieta i jeden skok to w porządku ale od tego się zaczyna. Znacznie łatwiej ogarniać mniejsze, nazwane (nazwą metody) fragmenty kodu.

W dobrym kodzie metody są tak proste że w ogóle nie musisz ich analizować bo z nazwy, argumentów i zwracanych wartości od razu wiadomo do czego służą; w przypadku jednej większej metody z goto musisz ją przeanalizować w całości.

No ja przejąłem kod .Netowy po jakimś juniorze z juesej. Metoda na 1k linii. goto użyte w kilku miejscach. Analiza tego to jest dramat. Pierwszy raz widziałem goto w kodzie produkcyjnym 😛 Projekt blazorowy nie starszy niż 1.5 roku :)

Akihito
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Śląsk
  • Postów: 248
4

Nie wierzę, 2025 rok, a jakiś ziomek pyta o wyjście z zagnieżdżonej pętli, a wy mu goto mówicie. Szkoda, że nikt jeszcze nie wpadł na to, żeby zrobić sobie exception flow i rzucać wyjątkiem, a catchem łapać poza pętlami.

Ale żeby nie było spamu i hejtu – autorze, masz tak naprawdę omawiane wcześniej dwa rozwiązania:

  1. Wychodzisz, używając return – możesz nic nie zwracać. 😉
  2. Używasz podwójnego break – na 90% będziesz potrzebował jakiejś flagi.
loza_prowizoryczna
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1628
0
Akihito napisał(a):

Szkoda, że nikt jeszcze nie wpadł na to, żeby zrobić sobie exception flow i rzucać wyjątkiem, a catchem łapać poza pętlami.

To też byłoby ok gdyby nie fakt że fakt że piszemy w kontekście C# i .NET gdzie chyba rzucenie wyjątku powoduje stack unwinding co chyba jest kosztowne 🫤 W normalnych językach jak Swift nie ma exceptionów a try catch to syntactic sugar na przekazanie do funkcji dodatkowego wskaźnika error i niejawne zwrócenie go w wyniku co jest praktycznie bezkosztowe.

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6965
0
Akihito napisał(a):

Nie wierzę, 2025 rok, a jakiś ziomek pyta o wyjście z zagnieżdżonej pętli, a wy mu goto mówicie.

Tylko przedstawiamy goto jako jedno z możliwych rozwiązań...

WeiXiao
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5226
1

@Akihito

Używasz podwójnego break – na 90% będziesz potrzebował jakiejś flagi.

Podwójne brejki, dodatkowe flagi, i wszystko tylko po to, aby nie użyć goto :D

Jakby młotki miałe złą reputację to gwoździe też byś wbijał kamieniami?

AD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 50
0

Jak komuś zależy na trzymaniu sie na siłę tylko składni for można jeszcze użyc tuples

Kopiuj
for ((int i, bool exit)topLoop = new(); topLoop.i < 10 && !topLoop.exit; topLoop.i++)
{
    for (int j = 0; j < 10 && !topLoop.exit; j++)
    {
        topLoop.exit = true;
    }
}

albo posłużyć się int-em zamiast bool'a

Kopiuj
for (int i = 0, exit = 0 ; i < 10 && exit is 0; i++)
{
    for (int j = 0; j < 10 && exit is 0; j++)
    {
        exit = 1;
    }
}

jednak i wtedy drugi warunek na sprawdzanie wartości zmiennej trzeba dodawać do każdego poziomu pętli

obscurity
  • Rejestracja: dni
  • Ostatnio: dni
1
WeiXiao napisał(a):

Jakby młotki miałe złą reputację to gwoździe też byś wbijał kamieniami?

w tej metaforze to raczej goto jest kamieniem a ty po wynalezieniu młotka dalej chcesz używać kamieni bo świetnie działają i nie trzeba iść do budowlanego i wmawiasz ludziom że chcą używać młotków tylko dlatego że ktoś im powiedział że kamienie są przeżytkiem

AbcDefGhi napisał(a):

Jak komuś zależy na trzymaniu sie na siłę tylko składni for można jeszcze użyc tuples
albo posłużyć się int-em zamiast bool'a

tak durne że już wolę chyba to goto...
ale jak już ciągniemy temat to chyba nikt nie wspomniał że nie trzeba żadnej flagi, wystarczy spełnić warunek zewnętrznych pętli i przestawić np i na koniec

Kopiuj
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
  if (warunek) {
    //zakończ iteracje na wszystkich pętlach
    a = x1;
    break;
  }
}

// edit: a nie, jednak @andrzejlisek o tym wspomniał, tylko niepotrzebnie dodał do tego jeszcze 1. No i w takim przypadku przyda się ulubiony przez weixiao komentarz mówiący po co jest ta linijka, bo podobnie jak z goto - przebieg takiego kodu nie jest jasny

loza_prowizoryczna
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1628
0
obscurity napisał(a):

w tej metaforze to raczej goto jest kamieniem

Innymi słowy wspomniane wyżej labeled statements (takie doprecyzowane goto) to już maczuga czy może bardziej katapulta? Bo nowe języki je implementują.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.