Czy dobrą praktyką jest nazywanie zwracanej zmiennej „wynik”? [Zamknięte]


44

Czy dobrą praktyką jest wywoływanie zmiennej, którą metoda zwraca z nazwą zmiennej result?

Na przykład:

public Zorglub calculate() {
    Zorglub result = [...]
    [...]
    return result;
}

Czy powinienem to nazwać według rodzaju?

public Zorglub calculate() {
    Zorglub zorglub = [...]
    [...]
    return zorglub;
}

Widziałem oba na wolności, jeśli muszę wybrać jeden, jakie powody mogłyby sprawić, że wolę pierwsze lub drugie (lub lepsze imię)?

Myślę głównie o Javie.


73
Widziałem również ofTheJediużywane do tego celu. To nie jest zalecenie, tylko mówię, że to widziałem. Zorglub ofTheJedi = //...; return ofTheJedi;

7
Zwykle nazywam to „retval” (wartość do zwrócenia), ale to mniej więcej to samo, co „wynik”, na który oddałbym swój głos.
Zeta Two

5
Każdy ma inną odpowiedź, wszystkie są podobne, ale różne i ważne, pytanie nie jest dobrowolnie subiektywne, ale odpowiedzi są. To bardziej ankieta.
ZJR,

16
Powiedziałbym, że „wynik” jako zmienna jest w porządku, ale „obliczanie” jako funkcja absolutnie nie jest.
Kaz Dragon

2
Czy współpracujesz z wieloma byłymi programistami Delphi?
Peter Turner

Odpowiedzi:


48

Jeśli jest to zmienna metody, tak naprawdę zależy to od czytelności.

Ponieważ masz już nazwę typu zarówno w deklaracji zmiennej, jak i typie zwracanej metody, równie dobrze możesz użyć result- jest to opis roli zmiennej.


40

Czytanie krzyżowe jest łatwiejsze, jeśli zmienna ma nazwę result. To wyjaśnia twoją intencję.


2
+1 To jest główny punkt. Wiem, co oznacza wynik w dowolnym kontekście, wystarczy spojrzeć na kod.
Xeoncross,

1
Zgadzam się, użycie typu zmiennej nie pomaga zrozumieć, że zamierzasz ją zwrócić. W tych prostych przykładach łatwiej jest zobaczyć powrót bez przewijania lub wyszukiwania, ale szybciej jest wiedzieć z góry, jaka jest zwrócona wartość funkcji. Ważne jest również, aby go zainicjować, jak w przykładzie.
nycynik

17

Jeśli potrzebuję zmiennej zwracanej (co w rzeczywistości zdarza się rzadko), zawsze wywołuję ją reti zawsze definiuję bezpośrednio pod nagłówkiem funkcji. Funkcja ma już nazwę, która mówi wszystko o tym, co zwraca.

Gdybym miał myFunction, mógłbym nazwać zmienną zwracaną, myFunctionReturnValueaby powiedzieć dokładnie to samo, tyle że musiałbym to wyraźnie powiedzieć za każdym razem. Ponieważ funkcje powinny być na ogół krótkie, nie ma potrzeby takiej jawności. I nawet jeśli zgubię ścieżkę, mogę przejść do deklaracji i wylądować tuż pod definicją funkcji.

Ale każda inna nazwa, która nie domyślnie (jak retlub result) lub jawnie (jak myFunctionReturnValuelub myFunctionResult) stwierdza, że ​​jest to zmienna zwracana przez bieżące funkcje, jest zbyt ogólna.

W twoim drugim przykładzie zorglubjest to okropny wybór. Wszystko, co naprawdę mówi mi, to to, że utworzyłeś zmienną, której nazwa jest równa adnotacji typu znajdującej się obok nazwy. Jest tak pomocny jak int someIntlub Zorglub z.

W twoim pierwszym przykładzie, kiedy patrzę na kod, najpierw widzę nazwę funkcji, która mówi mi, że ta funkcja oblicza a Zorglub. Kiedy czytam drugi wiersz, widzę „ok, oto zorglub, który zostanie zwrócony, ale najwyraźniej nie można go od razu zwrócić i dlatego jest przechowywany w resultzmiennej” (na marginesie: jeśli jesteś nie zamierzając ponownie przypisywać wartości, najlepiej zadeklarować zmienną jako ostateczną, aby to przekazać), a potem myślę „więc zobaczmy, co się z nią stanie, zanim zostanie zwrócona”. Inaczej niż w pierwszym przykładzie I nie trzeba właściwie czytać dalej, niż wiedzieć, że to jest zmienną, która będzie zwracana i że chcę pójść w ciele funkcji, jeśli chcę, aby to zrozumieć.

Możesz przeczytać więcej na temat programowania Spartan , które jest raczej związane z twoim pytaniem.


8
+1 dla „zorglub to okropny wybór”. Nie ma ziemskiego powodu do posiadania nazwy zmiennej w jakimkolwiek kontekście, która jest identyczna z nazwą typu (pomniejszoną o kapitał początkowy). Deklaracja mówi ci o typie zmiennej - nazwanie zmiennej po typie nie jest lepsze niż wywołanie zmiennych x1, x2, x3 i tak dalej. Nazwa każdej zmiennej powinna wyrażać, do czego służy lub co robi. Moją preferowaną nazwą dla zmiennej w tym konkretnym przypadku jest to Return - ponieważ zmienna odwołuje się do obiektu, który ma zostać zwrócony. W rzeczywistości wiele moich nazw zmiennych zaczyna się od „do”.
Dawood mówi, że przywróć Monikę

21
@DavidWallace - to zbyt silny absolut. Mam klasę o nazwie Container. Jeśli mam metodę, która modyfikuje ilość, mogę powiedzieć, var container = getContainer(id); container.Quantity += 1; że jest to z pewnością czytelne, jeśli kontekst metody działa tylko na jednym kontenerze, i to wszystko. Nazywanie tego theContainerWeAreGoingToAdjustTheQuantityOfjest po prostu śmieszne.
Scott Whitlock,

4
@David, nie zgadzam się. Weźmy sytuację, w której masz kilka zmiennych lokalnych, z których każdy jest innego typu (powiedzmy Użytkownik, Kierownik i Dział). Załóżmy, że zadaniem jest połączenie użytkownika z działem i zespołem kierownika. IMHO w porządku jest nazywanie tej instancji użytkownika po prostu user(w przeciwieństwie do userToJoinThisDepartmentAndManager? Lub jaki byłby twój wybór?)
Péter Török

10
Drobny nitpick: Nienawidzę widzieć „ret” lub „rv” lub innych skróconych wariantów wyników / returnValue. „wynik” nie jest zbyt długi i nikt nie musi zachowywać znaków.
Kristopher Johnson

2
@KristopherJohnson: „wynik” nie jest zbyt długi, ale również nie oznacza „wartości zwracanej”. Zwracane wartości nie zawsze są wynikiem obliczeń, i odwrotnie, wyniki obliczeń nie zawsze są zwracanymi wartościami. Przypuszczam, że możesz nazwać swoją wartość zwrotu returnValue, ale retjest ona tradycyjna, podobnie jak inti char.
ruakh

12

W drugim przykładzie łączysz rodzaj wyniku z tym, co to jest .

Zorglub zorglub;

po prostu mówi mi, że to Zorglub, dwa razy. Trzy razy, jeśli będę chciał przeczytać typ zwracanej metody. Jednak,

double variance;

na przykład, daje mi pojęcia o tym, co obie wartości środków pod względem semantyki programu. Może, ale nie musi, być bardziej zrozumiałe niż zwykłe wywołanie go result, w zależności od wielkości metody - to wywołanie oceny dla każdej metody IMO.


8

Jeśli grasz z wielu Zorglub obiektów w metodach, to „może” pomyłki i powrócić niewłaściwy, lub / i można ulec pokusie, aby wymienić pozostałe zorglub1, zorglub2itd

Jeśli go nazwiesz result, nie ma szans, abyś popełnił taki błąd. Poza tym uważam, że to dobre imię; Też widziałem returnedValuelub returnedObjectkilka razy, jest to również jasne, choć trochę długie.


5

Osobiście nie czuję się komfortowo, używając resultnazwy zmiennej. W porządku, mówi mi, że powiązana wartość jest wynikiem pewnych obliczeń - jednak wydaje mi się, że jest to zgodne z około (lub ponad) 90% zmiennych / pól używanych w programie.

Ponadto, jak zauważyło kilka innych odpowiedzi, można go użyć do oznaczenia wartości, która ma zostać zwrócona z metody / funkcji. Jednakże, jeśli moje metody będą krótkie, skoncentrowane na robieniu tylko jednej rzeczy i konsekwentnym utrzymywaniu jednego poziomu abstrakcji, nie będę mieć wielu zmiennych lokalnych i nie będzie łatwo zobaczyć, co metoda zwróci.

Dlatego wolę, aby moje metody były krótkie i czyste, i nadaj nazwom moje zmienne, aby wyrażały znaczenie posiadanej wartości, a nie jej lokalną rolę w otaczającej metodzie. Jednak (np. W starszym kodzie) z Zorglub resultpewnością może być łatwiejszy do zrozumienia niż Zorglub zorglub.


12
Nie jest wywoływany, resultponieważ jest wynikiem pewnych obliczeń; nazywa się resultto, ponieważ jest wynikiem tego obliczenia. Działa to również jako jego znaczenie IMO, nawet jeśli nie jest to możliwie najbardziej szczegółowe znaczenie. Wyrażanie znaczenia jest złote, ale intencja i idiomy też mogą być cenne. W tym przypadku jest to trochę kompromis.
Supr

@Supr: Jaką nazwą byś opisał wynik jakiegoś innego obliczenia, które zostanie użyte tylko w następnej instrukcji lub dwóch (np. if (result >= 0) numChars+=result; else break;I których znaczenie będzie oczywiste z obliczeń?). Moim zdaniem, wartość że będą zwracane z tej funkcji powinien być nazywany ret, natomiast wartość który został zwrócony z ostatniej wywołanej funkcji powinno być result. Zauważ, że resultmoże być bardziej znaczące niż dłuższa nazwa, jeśli wartość zwracana przez funkcję może np. Reprezentować albo ilość, albo kod błędu.
supercat

@ supercat, nazwałbym to na podstawie tego, czym było obliczenie lub na jakiej wartości ma służyć. Nawet jeśli zostanie użyty tylko w następnym obliczeniu, nadal poprawia czytelność, jeśli jest dobrze nazwany. W twoim przykładzie nie mam pojęcia, co to znaczy resultani co kod robi na wyższym poziomie. Musiałbym odnieść się do tego, gdzie jest ustawiony, aby zobaczyć, skąd bierze się jego wartość i co to jest. Coś w rodzaju addedCharslub matchedCharsbyłoby bardziej przejrzyste i pomogłoby ujawnić, co robi kod, i nie wymagało mentalnego żonglowania tym i powiązanymi result = ...:)
Supr

@Supr: Problem polega na tym, że w wielu przypadkach różne zakresy zwracanych wartości mogą oznaczać różne rzeczy. Na przykład procedura odczytu pakietu do bufora o określonym rozmiarze może zwrócić liczbę bajtów, jeśli pakiet został odebrany, lub liczbę ujemną wskazującą, że pakiet był (i nadal jest) oczekujący, że jest zbyt duży dla bufora, lub naprawdę duża liczba ujemna wskazująca na inny błąd. Przechowywanie zwrotu resulti sprawdzanie go pod kątem tych kryteriów wydaje się bardziej naturalne niż próba wymyślenia opisowej nazwy obejmującej wszystkie z nich.
supercat

@ superupat, Używanie retzamiast resultwydaje mi się w porządku. Moim zdaniem jest to nieco mniej jasne, ponieważ jest skrócone i nie jest podobne do rzeczownika, ale jeśli jest używane konsekwentnie, to jest równoważne result.
Supr

1

Ja osobiście używam nazwy resultdla wartości, która ma zostać zwrócona z funkcji / metody. Wyraźnie wskazuje, że jest to wartość do zwrócenia. Nazwanie go według typu nie wydaje się przydatne, ponieważ może istnieć więcej niż jedna zmienna tego samego typu.


Uhm, z pewnością fakt, że powie „powrócić”, zanim zostanie zwrócony, jest wystarczająco wyraźny? Powinieneś opisać, co z tym zrobisz, a teraz „jak”. Dlaczego nie nazwać go sumą, wynikiem lub czymś innym opisującym cel, wtedy twój kod będzie gotowy „zwróci sumę” lub podobny ...
Dave

@Dave Niekoniecznie, szczególnie jeśli masz kilka obiektów tego samego typu, z których wszystkie mogą zostać zwrócone, celem tej metody jest ustalenie, który z nich należy zwrócić.
Andy,

@Andy, rozumiem twój punkt widzenia, ale w rzeczywistości nie wyobrażam sobie pisania takiej funkcji. Jeśli to jest powód napisania takiej funkcji, wygląda na to, że należy ją podzielić na mniejsze, bardziej zrozumiałe funkcje.
Dave

1

Co za różnica? są tam tylko 2 różne słowa, które zrobią to samo, więc prawdziwym problemem jest to, które z nich brzmi dla ciebie bardziej wyraźnie?

„Wynik” lub „zorglub”.

Wolałbym użyć ZorglubResultna początek, aby zobaczyć, że wynik zwraca się z Zorglub łatwiejszego do porównania z innymi wynikami, które możesz mieć, a jego wynik, jak widać.


1

czy powinienem nazwać go według rodzaju?

Nie, nigdy. Nazywa się to węgierskim systemem i jest trywialnie przestarzałe na myśl o użyciu programu, który może wyświetlać typ dowolnej zmiennej w dowolnym momencie.


1

Ilekroć musisz nazwać cokolwiek w kodzie, powinieneś podać nazwy opisowe, znaczące i czytelne. Przypadek zmiennej zwracanej jest szczególnie dobrym przykładem na to, że ludzie narzekają na nazewnictwo.

Jeśli masz funkcję o wyraźnej nazwie i potrzebujesz tylko jednego wiersza kodu, możesz całkowicie pominąć nazewnictwo. Uczynienie metod krótkimi i pojedynczymi jest zawsze ideałem, do którego powinieneś dążyć. Jednak zdarza się, że czasami trzeba uzupełnić funkcję kilkoma liniami kodu. W takich przypadkach zawsze wskazane jest, aby nazwać zmienną tak, aby pasowała do celu funkcji.

Jeśli celem funkcji jest zwrócenie wyniku obliczenia lub algorytmu decyzyjnego, to czy resultjest to całkowicie odpowiednia nazwa dla zmiennej, ale co, jeśli funkcja zwraca element z listy? Co się stanie, jeśli twoja funkcja służy do jakiegoś innego celu, który nie ma nic wspólnego z matematyką lub listami? W takich przypadkach lepiej jest podać zmiennej znaczącą nazwę, która odnosi się do tego, dlaczego funkcja została utworzona. Jasne, możesz po prostu użyć wyniku, jeśli chcesz, ponieważ jest to nazwa, która prawdopodobnie nie będzie kolidować z niczym innym, jednak z punktu widzenia czytelności bardziej sensowne jest nazwanie zmiennej bardziej sensownie i w kontekście.


0

Lubię je łączyć, pokazuje, co to jest i że ma zostać zwrócone.

więc w twoim przykładzie będzie to wynikZorglub

jeśli to, co to tak naprawdę nie ma znaczenia, byłoby po prostu wynikiem (nie resultString)


Nieźle, ale myślę, że musiałbyś zmienić nazwę swojej zmiennej, jeśli zmieni się typ zwrotu. Przy nowoczesnym IDE i tak robi się to za pomocą jednego lub dwóch kliknięć.
Jalayn

@Jalayn Tak, ale jeśli ten typ byłby poza nazwą, to zmiana, której wcale nie trzeba by robić. (Jeśli metoda jest wystarczająco długa, aby prosta nazwa nie była jasna, prawdopodobnie jest za długa i powinna zostać zrefaktoryzowana.)
Donal Fellows

@DonalFellows Całkowicie się z tobą zgadzam. Im mniej zmian zobaczysz podczas aktualizacji z repozytorium źródłowego, tym lepiej.
Jalayn

OK zgodził się, że kiedy zmienisz typ zwracany, możesz zapomnieć zmienić go również w nazwie zmiennej, to jest problem. Do tej pory nie stanowiło to dla mnie problemu. Nadal lubię pokazywać podwójną intencję w nazwie, ale przy mniejszym już dobrym kodzie intencji może to być również przesada. Przekonaliście mnie. Jeśli odtąd odczuję potrzebę wywoływania moich zmiennych w ten sposób, dokonam refaktoryzacji, dopóki nie poczuję takiej potrzeby. Dzięki
KeesDijk,

0

Nie widzę żadnej różnicy między ustawieniem wartości zwracanej w pewnym momencie, a następnie użyciem warunkowych, aby pominąć cały kod, który mógłby ją zmodyfikować, i returnod razu, więc wybieram bezpośredni zwrot, dlatego nie ma resultzmiennej.

Jeśli masz wartość pośrednią, która może lub nie może zostać zmieniona przez kod warunkowy, to nie jest to wynik (jeszcze), więc na pewno nie powinien być tak nazwany.


0

Kiedy pracowałem w C ++ i myślę, że może to dotyczyć Java.

na przykład

int Width() const
{
    Requires(....);
    Requires(....);

    //calculation

    Ensures(...);
    Ensures(...);
    return Result;
}

Jest to projekt na podstawie umowy, ponieważ blok zapewniający powinien znajdować się na końcu metody. Ale powrót musi być ostatni. Mieliśmy zasadę, że zwracanie Wynik był jedyną rzeczą, która mogła być zgodna z blokiem zapewnienia.


0

W funkcji rekurencyjnej często skuteczne jest przenoszenie wyniku krok po kroku, aby zoptymalizować ogon. Aby zasygnalizować użytkownikowi, że nie musi on podawać parametru, uzasadnione może być nazwanie parametru „wynik”:

def removeOccurence [A] (slice: Seq[A], original: Seq[A]) = {
  @scala.annotation.tailrec
  def remove (leftOriginal: Seq[A], result: Seq[A]) : Seq[A] =
    trimStart (slice, leftOriginal) match {
      case (h :: tail) => remove (tail, h +: result)
      case (Nil)       => result.reverse
    }
    remove (original, Nil)
}

Ale częściej używam „carry” i „sofar”, które widziałem na wolności, i które w większości przypadków są jeszcze lepsze.

Drugim powodem jest oczywiście to, że twój temat sugeruje słowo „wynik”, na przykład jeśli wykonujesz ocenę arytmetyczną. Możesz przeanalizować formułę, zastąpić zmienne wartościami i na końcu obliczyć wynik.

Trzeci powód został już podany, ale mam małe odchylenie: piszesz metodę, która wykonuje jakąś pracę, powiedzmy, że ocenia formę „max”.

def max = {
  val result = somethingElseToDo
  if (foo) result else default 
}

Zamiast nazywać wynik „wynikiem”, moglibyśmy nazwać go „maks.”, Ale w niektórych językach można pominąć nawiasy podczas wywoływania metody, więc max byłoby rekurencyjnym wywołaniem samej metody.

Ogólnie wolałbym nazwę, która mówi, jaki jest wynik. Ale jeśli ta nazwa jest już zajęta, być może przez więcej niż jedną zmienną, atrybut lub metodę, ponieważ istnieje pole GUI, reprezentacja ciągu, numeryczna i jedna dla bazy danych, użycie innej zwiększa prawdopodobieństwo pomyłki. W krótkich metodach od 3 do 7 wierszy „wynik” nie powinien stanowić problemu dla nazwy.


0

W Object Pascal nie jest to wybór. Musisz przypisać wartość do Resultzmiennej gdzieś w kodzie funkcji.

Przykład:

function AddIntegers( A,B: Integer): Integer;
begin
  Result := A + B; 
end; 

Więc dla mnie jest całkiem naturalne, że zmienna „Wynik” (lub „Retorno”, jak pisuję w języku portugalskim, aby uniknąć konfliktu nazw ze słowami zastrzeżonymi języka), aby otrzymać wartość zwracaną.

Oczywiście, jeśli jest to bardzo proste wyrażenie w języku pochodnym C, nie zawracam sobie głowy deklarowaniem zmiennej wynikowej - zwracając wyrażenie bezpośrednio.


0

nie chodzi tylko o to, jak nazwiesz wynik (jestem konkretny dla „r”), ale także o to, jak jest używany. na przykład, jeśli chcesz mieć zmienną return, to każda instrukcja return powinna ją zwrócić. nie mam „return r;” na końcu, ale posyp rzeczy takie jak „return m * x + b;” w całej metodzie / funkcji. użyj „r = m * x + b; return r; ”zamiast tego.


-1

wynik jest w porządku. Jestem w stanie zrozumieć kod na pierwszy rzut oka, więc nazwa zmiennej służyła temu celowi.

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.