Czy złą praktyką jest nazywanie nieużywanej zmiennej pojedynczym podkreśleniem?

44

Często, gdy składnia języka wymaga, abym nazwał zmienną, która nigdy nie jest używana, nadam jej nazwę _.

Moim zdaniem zmniejsza to bałagan i pozwala skupić się na znaczących zmiennych w kodzie. Uważam, że jest dyskretny, dlatego wywołuje efekt „poza zasięgiem wzroku, poza zasięgiem umysłu”.

Typowym przykładem tego, co robię, jest nazywanie podkwerend w SQL.

SELECT *
FROM
(
    SELECT *
    FROM TableA
    JOIN TableB
        ON TableA.ColumnB = TableB.ColumnB
    WHERE [ColumnA] > 10
) _ --This name is required, but never used here
ORDER BY ColumnC

Innym przykładem jest zmienna pętli, która nie jest używana.

array = [[] for _ in range(n)] # Defines a list of n empty lists in Python

Używam tej techniki bardzo oszczędnie, tylko wtedy, gdy czuję, że opisowa nazwa nic nie dodaje do kodu, iw pewnym sensie odbiera ją, dodając więcej nazw do zapamiętania. Pod pewnymi względami postrzegam to jako podobne do varsłowa kluczowego w C #, którego również używam oszczędnie.

Moi współpracownicy się nie zgadzają. Mówią, że nawet posiadanie pojedynczej (alfabetycznej) nazwy znaku jest lepsze niż _.

Czy się mylę? Czy to jest złą praktyką?

Kris Harper
źródło
4
Myślę, że nazwy zmiennych powinny być zgodne z teorią informacji, tzn. Długość jest logarytmicznym prawdopodobieństwem ich zastosowania (wspólne zmienne mają krótkie nazwy). Pojedyncza litera alfabetu wydaje się niewłaściwą drogą.
dan_waterworth
2
@dan_waterworth Używanie pojedynczych lub podwójnych znaków jako aliasów tabeli jest dość powszechną praktyką w skryptach SQL. Ponieważ zwykle musisz napisać wiele [table].[column]identyfikatorów, bardzo ułatwia to czytelność [T].[column]. To oczywiście zależy od scenariusza. Taka mała selekcja jest w porządku, ale jeśli skrypt byłby bardzo duży, mógłbym użyć bardziej opisowych nazw.
CodexArcanum
5
Wolałbym, żebyś użył „manekina”. Krzyczy mi to, że tam są, ponieważ język wymaga zmiennej, która nie ma kontekstu semantycznego poza tymi kilkoma liniami. _ nie czyta dobrze człowiekowi. (jeden z powodów, dla których nienawidzę PERL - nie mogę pisać ani czytać)
Chris Cudmore
1
Uwaga dodatkowa: to, co nazywasz, to tabela pochodna , a nie podzapytanie.
Nick Chammas
2
Słowo kluczowe var w języku c # nie ma tego znaczenia, jest to zwykła deklaracja zmiennej, z której wywodzi się typ.
Francesco De Vittori,

Odpowiedzi:

60

Wszystkie imiona powinny mieć znaczenie. Gdyby _był dobrze znanym standardem w Twojej firmie lub w szerszej społeczności, miałby znaczenie jako „nazwa, która nie ma znaczenia”. Jeśli nie, powiedziałbym, że to zła praktyka. Używaj opisowej nazwy do tego, do czego się odwołujesz, zwłaszcza że nazwa może mieć znaczenie w przyszłości.

Telastyn
źródło
13
+1. dummybyłoby dobrze, joined_abbyłoby lepiej.
Blrfl
5
+1, istnieje konwencja, w której pracuję nad użyciem „_” dla nieużywanych zmiennych. Myślę, że to dobra konwencja, ale zgadzam się z tą odpowiedzią w sprawie PO. Idealnie podstawy kodowe powinny wyglądać tak, jakby zostały napisane przez jedną osobę.
dan_waterworth
20
„_” jest dobrze znanym standardem w Pythonie.
Neil G
2
Z drugiej strony, jeśli Twoja firma korzysta z Perla, użycie $ _ może czasem wywołać zaskakujące zachowanie.
Nauczyciel
2
W prologu podkreślenie wskazuje, że zmienna będzie anonimowa i dlatego nie będzie używana.
Ivan
44

Powiedziałbym, że jest to dopuszczalna praktyka. Jest to rzadki przypadek, w którym uważam, że większość jest błędna i potrzebuje aktualizacji wiedzy na temat najnowszych pomysłów programistycznych. W wielu językach, szczególnie w językach funkcjonalnych opartych na ML, takich jak Haskell i OCaml, niezwykle często stosuje się je _jako „nieużywane” zmienne. Nawet Lua, która nie oferuje wsparcia dla jawnego języka, zachęca do korzystania z niego _jako symbolu zastępczego zgodnie z konwencją.

Kilka języków (Haskell, Lua i DI myślą z góry) również oferuje konwencję, w której zmienne, które prowadzą z podkreśleniem, nie generują ostrzeżeń kompilatora o „nieużywanej zmiennej lokalnej”, co czyni _najkrótszą nieużywaną nazwę zmiennej. Możesz użyć czegoś takiego, _unusedale zgadzam się z tobą, że to po prostu bałagan.

CodexArcanum
źródło
W konkretnym przypadku SQL zastanowiłem się nad tym i współpracownicy mogą tu mieć rację. Bardzo często używam pojedynczej dużej litery dla aliasów tabeli (i często R (esults) dla podselekcji). Myślę, że użycie *w selekcjach jest bardzo złą rzeczą, ponieważ jeśli tabela zmieni się, zestaw wyników również zmieni się nieoczekiwanie. Dlatego zwykle potrzebuję aliasu jednoznakowego do identyfikacji kolumn, które wybieram. Jeśli przestaniesz używać *, przestaniesz potrzebować „nieużywanej” nazwy.
CodexArcanum
11
Ściśle mówiąc, przynajmniej w Haskell, _jest wzorem, a nie zmienną. Jest to subtelna różnica, ale oznacza to, że możesz użyć jej wiele razy w czymś podobnym (x, _, _) = ..., podczas gdy wielokrotne wiązanie tej samej zmiennej byłoby błędem.
hammar
12

W Pythonie _jest definitywnie akceptowalny. Może jednak powodować konflikt z gettextaliasem _().

Inne częste konwencje dummy, unused; sam lub jako prefiks.

Niektóre narzędzia do analizy kodu znają te konwencje i nie wydają nieużywanych ostrzeżeń o zmiennych:

  • PyLint dla _lubdummy
  • PyDev dla każdej zmiennej, począwszy od _, unusedlubdummy
vartec
źródło
2
Ponadto użycie _zmiennych zastępczych w pythonie będzie kolidowało z _ostatnią zwróconą wartością. Np. W tłumaczu, jeśli robisz to 5*5na linii 1; wtedy w wierszu 2 _będzie wartość 25. Jeśli jednak ustawisz x,_ = (3,'not used'), przekonasz się, że _jest to teraz not usedzamiast ostatniej zwróconej wartości do ciebie del _. Prawdopodobnie nie powinieneś używać _ostatnio zwracanej wartości w prawdziwym kodzie; ale często przydaje się w tłumaczu podczas wypróbowywania nowych rzeczy.
dr jimbob
4
Cóż, _ponieważ ostatnia zwrócona wartość działa tylko w interaktywnej powłoce.
vartec
To samo dotyczy Lua. Używanie _ jest standardową praktyką
sylvanaar
11

Zależy to od ekosystemu, w którym ten kod będzie żył. Jeśli _jest akceptowanym standardem wskazującym „zmienną fikcyjną” / „nieużywaną moc wyjściową”, to należy go trzymać. Jeśli nie, dowiedz się, co to jest i skorzystaj z niego.

Niektóre języki programowania (np. Haskell) mają nawet ten „specjalny” identyfikator wbudowany w ich składnię do dokładnie wymienionych celów.

tdammers
źródło
5

Ostrożnie, _ ma już pewne znaczenie w niektórych językach

W Pythonie:

9,6 Zmienne prywatne i odniesienia lokalne

wprowadź opis linku tutaj Zmienne instancji „Prywatne”, do których nie można uzyskać dostępu, chyba że z wnętrza obiektu nie istnieją w Pythonie. Istnieje jednak konwencja, po której następuje większość kodu w języku Python: nazwa poprzedzona znakiem podkreślenia (np. _Spam) powinna być traktowana jako niepubliczna część interfejsu API (niezależnie od tego, czy jest to funkcja, metoda czy element danych) . Należy to uznać za szczegół implementacji i może ulec zmianie bez powiadomienia.

Jest też inna wzmianka w PEP 8 (Przewodnik po stylu dla kodu Python):

Opisowy: Style nazewnictwa

_single_leading_underscore: słaby wskaźnik „do użytku wewnętrznego”. Np. Z importu M * nie importuje obiektów, których nazwa zaczyna się znakiem podkreślenia.

W C #:

Zwykle służy do oznaczania zmiennych prywatnych, które mają właściwości publiczne / wewnętrzne. Ale w tych czasach praktyka jest ogólnie odrzucana .

W JavaScript:

Istnieje biblioteka o nazwie underscore.js, która używa podkreślenia jako prefiksu niestandardowych rozszerzeń prototypów.

Przykład:

var object = { some:'stuff' };
var newObject = _.clone(object);

Co prowadzi mnie do mojego punktu. Co jest nie tak z klasycznymi konwencjami zmiennych zastępczych.

var i, j, k, l; // iterator placeholders
var x, y, z, xx, yy, zz // value placeholders
var foo, bar, bas, fixx, buzz, qux, etc... // demonstration placeholders

Po co używać niestandardowej konwencji, którą niektórzy mogą błędnie interpretować, skoro dostępnych jest już wiele popularnych konwencji?

Evan Plaice
źródło
W Scali: jest to symbol wieloznaczny / symbol zastępczy, ale jako symbol zastępczy możesz odwoływać się do niego tylko raz .
Rex Kerr
@RexKerr Ciekawe. Jeśli chcesz, możesz to zmienić w odpowiedzi. Chciałbym, ale nie znam Scali.
Evan Plaice
Komentarz powinien zrobić. Każdy, kto korzysta ze Scali, będzie wiedział, a każdy, kto nie korzysta ze Scali, prawdopodobnie nie będzie miał kompatybilności ze Scalą na szczycie listy powodów, dla których powinien / nie robić czegoś.
Rex Kerr
Myślę, że użycie jednego z tych „zastępczych” symboli zastępczych dla nieużywanych zmiennych byłoby złą praktyką, ponieważ sprawiłoby, że pomyślałem, po pierwsze, „dlaczego, do cholery, ten facet nie nazwał tego lepiej?” i po chwili odkryłem, że to dlatego, że zmienna nie jest używana.
igorsantos07
@ igorsantos07 Całkowicie się zgadzam. Wolę nadać opisową nazwę, nawet w przypadku zmiennych tymczasowych. Celem tej odpowiedzi jest wykazanie, dlaczego podkreślenie nie jest dobrym wyborem dla konwencji nazewnictwa; ze względu na jego istniejące znaczenie w wielu językach.
Evan Plaice,
2

Używam do tego „manekina”. Lub „bzdura”, jeśli tylko coś testuję :) Nazwij swoje zmienne, aby opisać, jakie są. Jeśli są to atrapy nieużywane zmienne, nazwij je jako takie.

Phillip Schmidt
źródło
0

Uważam to za złą praktykę, ponieważ

  • nie powinieneś mieć niewidocznej zmiennej w swoim kodzie. Jeśli uważasz, że powinieneś, powód może być prawdopodobnie omówiony.

  • język Go używa tego słowa kluczowego, aby wskazać, że żadna zmienna nie jest celem jednego z wielu zwrotów funkcji. Jeśli twój język nie ma wielu zwrotów, nie jest potrzebny. Konwencja nazewnictwa zaszkodzi Ci w dniu, w którym będziesz używać języka, używając _ jako standardowej notacji językowej.

(Nie znam Pythona: czy ten konstrukt jest naprawdę potrzebny?)

Denys Séguret
źródło
2
Jeśli użyjesz go do filtrowania wielu zwrotów, konsekwencją jest również użycie go do argumentów funkcji fikcyjnej. W rzeczywistości nie ma między nimi dużej różnicy: w językach funkcjonalnych dopasowujących wzorce możesz pisać let (a,b,_) = f(x,y,z)równie dobrze let f(x,y,_) = (g(x),h(x),g(y)), czy cokolwiek innego. - I tak, często przydatne są parametry zastępcze: nie jako jedyna definicja funkcji, ale dla funkcji polimorficznej lub z alternatywnymi definicjami dopasowanymi do wzorca jest to często rzeczą naturalną.
lewo około
1
Twój drugi punkt jest sprzeczny z twoim głównym punktem: w Go oznacza to w zasadzie to samo, co „Nie mam pożytku z tej wartości”.
Casey Kuball
0

Może być poprawny pod względem składniowym i może być OK jako część standardu.

Powiedziawszy to, chciałbym poprosić kogoś o zmianę w recenzji kodu. Nigdy też nie wprowadziłbym go do standardu kodowania i próbowałbym go usunąć z istniejącego. Jest po prostu trudniejszy do odczytania i nie ma wielkiego znaczenia.

Alan Delimon
źródło
0

Myślę, że to źle, ponieważ:

1) Trudniej to zobaczyć, ponieważ nie ma wielu pikseli.

2) Jeśli jest więcej niż jeden _, skąd wiesz, który? - lub że nowy programista „przestrzegał zasad” i utrzymywał ich wyjątkowo lokalny zasięg?

3) Jest to praktyka, która nie jest pomocna. Używanie pojedynczych liter zmiennych to tak stara szkoła (tj. Moje oryginalne wykształcenie!). Zobaczę je ... a potem dodam komentarze, by powiedzieć, co robi kod, a to jest zła praktyka w dzisiejszym świecie. Używam długich nazw zmiennych tak często, jak to możliwe, więc każdy, bez względu na poziom programowania lub znajomość kodu, może po prostu „czytać” prawie jak angielski. Używanie nazw 1-literowych jest niezwykle powszechną praktyką w przypadku starszych kodów i starszych programistów (znowu obejmuje mnie), ale to nie czyni tego w porządku.

śmieciowy
źródło
9
„skąd wiesz, którego” nie znasz : właśnie o to chodzi, nie używasz zmiennej. Nie ma więc znaczenia, czy _jest już używany w zasięgu zewnętrznym; ten zostanie wtedy ukryty (lub cokolwiek zrobi Twój język w takich przypadkach), ale i tak żaden z nich nie zostanie użyty.
lewo około
0

Aby uniknąć kolizji w przestrzeni nazw i umożliwić debugowanie, w przypadku gdy jedyną wskazówką jest nazwa zmiennej, lepiej nazwać ją „join_ab_unused”.

Zainspirowany przez Birfl.

Brzeszczot
źródło
0

Tak, to zła praktyka z dwóch powodów:

  1. Prefiks nieużywanej zmiennej znakiem podkreślenia nie jest powszechnie akceptowanym standardem. Prawdopodobnie zostanie zignorowany jako „niewtajemniczony”.
  2. Widziałem, jak niektórzy ludzie poprzedzają prywatne zmienne członkami znakiem podkreślenia, a twój standard bardzo pomieszałby takie osoby.
Jim G.
źródło
0

To, co próbujesz zrobić, to napisać w ładniejszej wersji SQL, która nie ma problemu z wymuszeniem wymyślenia nazwy czegoś bezużytecznego.

Podkreślenie jest prawie niewidoczne, więc wygląda na to, że jesteś w tym języku. Gdyby tylko identyfikator mógł być użyty jako identyfikator, byłoby idealnie, prawda?

Ale nie jesteś w innym języku, a to, co robisz, nie jest czystym sposobem na rozszerzenie języka.

Kaz
źródło
0

To zależy od języka. W Javie tak, jest to złe i może być niebezpiecznym trendem do dodawania do twojego kodu, głównie dlatego, że narzędzia wykorzystujące odbicie nie radzą sobie zbyt dobrze z podkreśleniami, ponieważ są poza konwencjami nazewnictwa zmiennych Java. W Pythonie jest to również złe, ale nie tak złe. W clojure jest w 100% w porządku, aw rzeczywistości idiomatyczne jest używanie _ jako symboli zastępczych w instrukcji let.

Pamiętaj, że każdy język ma swoją własną składnię i zestaw idiomów, więc musisz oceniać dobre / złe pod względem tych idiomów, a nie w kategoriach bezwzględnych.

jayunit100
źródło
5
Nie zgadzam się, że jest to zła praktyka w Pythonie. Jest to szeroko rozumiana konwencja
Daenyth
0

Byłoby źle w perlu, który używa $ _ (a czasami _) jako specjalnej zmiennej.

Ogólnie rzecz biorąc, trzymałbym się z dala od tego tylko dlatego, że _ wydaje się być specyficzną dla języka zmienną. Gdybym zobaczył twój kod, szukałbym w dokumentacji tego, czym był _, dopóki nie zdałem sobie sprawy, że to tylko manekin. Nic złego z DUMMY, $ DUMMY, cokolwiek.

Rich Homolka
źródło
0

Unikałbym podkreśleń na początku różnych wersji, chyba że byłeś pewien, że nie wskazują one na coś innego w danym języku lub frameworku, który jest często używany. Na przykład w Pythonie podwójny znak podkreślenia wskazuje na magiczną zmienność. W JQuery i innych bibliotekach JS pojedynczy znak podkreślenia wskazuje na zmienną rezerwową w przypadku zastępowania przestrzeni nazw. Jest to również popularna konwencja nazewnictwa dla plików dołączanych, które z kolei mają tendencję do przenoszenia na kod, który obsługuje zmienne w formie.

Erik Reppen
źródło