Właśnie znalazłem tę funkcję w projekcie, nad którym pracuję:
-- Just returns the text unchanged.
-- Note: <text> may be nil, function must return nil in that case!
function Widget:wtr(text)
return text
end
Szkoda, że programista nie działa już w firmie. Dlaczego mielibyśmy tworzyć funkcje, które nic nie robią, ale zwracają wywołany parametr?
Czy taka funkcja ma jakieś zastosowanie, nie wymienione w tym przykładzie, ale ogólnie w każdym razie?
Spowodowany
function aFunction(parameter)
return parameter
end
Kończy się w
aFunction(parameter) == parameter
Dlaczego miałbym pisać coś takiego
aFunction(parameter) == whatIWantToCheck
zamiast
parameter == whatIWantToCheck
?
functions
parameters
lua
method-chaining
Sempie
źródło
źródło
this
.int getParam(int param) { //DO NOTHING return param; }
Z perspektywy łączenia metod jest to całkowicie zbędne i niepotrzebne wywołanie, ponieważ możesz pozostawić funkcję OP poza łańcuchem metod i nie zrobiłoby to żadnej różnicy.new Foo()->method();
nie była poprawna składnia, afunction with($what) { return $what; }; with(new Foo())->method();
jako obejście zastosowano konstrukcje podobne .Odpowiedzi:
Twoje pytanie jest trochę jak pytanie o wartość liczby zerowej, jeśli za każdym razem, gdy dodasz ją do czegoś, otrzymasz tę samą wartość. Funkcja tożsamości jest jak zero dla funkcji. Niby bezużyteczne samo w sobie, ale czasami przydatne jako część wyrażenia wykorzystującego funkcje wyższego rzędu, w którym można przyjąć funkcję jako parametr lub zwrócić ją w wyniku. Dlatego większość funkcjonalnych języków programowania ma
id
lubidentity
w swojej standardowej bibliotece.Innymi słowy, jest to przydatna funkcja domyślna. Tak jak możesz chcieć ustawić
offset = 0
jako domyślną liczbę całkowitą, nawet jeśli to powoduje, że offset nic nie robi, to może być przydatne, aby móc ustawićfilterFunction = identity
jako funkcję domyślną, mimo że filtr nic nie robi.źródło
filter
wyższego rzędu. Funkcja pierwszego rzędufilter
ma typ[a] -> [a]
,.OrderBy(x => x)
Pewnie. Wyobraź sobie zewnętrzny interfejs API, który umożliwia pobieranie rzeczy z absolutnie potrzebnych miejsc, ale musisz określić kryteria filtrowania i formaty wyjściowe dla każdego zapytania, nawet jeśli chcesz uzyskać wszystkie wyniki i uzyskać je dokładnie tak , jak są przechowywane.
Następnie musisz wymyślić trywialną funkcję „akceptuj wszystko” i trywialną funkcję „powrót bez zmian”, aby uzyskać dostęp do danych.
wtr
jest właśnie takim trywialnym pseudo-formatatorem. Jeśli często używasz tego interfejsu API, może być bardzo przydatne, aby ta funkcja pseudo-pomocnika leżała w pobliżu, zamiast tworzyć anonimową funkcję za każdym razem, gdy o coś zapytasz. (Można rozważyć nazywając jąidentity
zamiastwtr
tak, to od razu jasne, że nic nie robi.)źródło
null
jako argumentu, użyj pustej funkcji filtrowania, która filtruje „nic”, aby program przestał narzekać.WHERE
klauzulę? To luźno kwestia cukru syntaktycznego. Zasadniczo brakWHERE
klauzuli jest dokładnie taki sam, jakbyś miałWHERE
klauzulę, która po prostu idzie do przodu i zezwala na wszystko. Fakt, że projektanci SQL nie pozwalają określićWHERE
klauzuli, zamiast zmuszać ją do odłożenia, nawet gdy akceptuje wszystko, jest mniej więcej składniowym cukrem, i właśnie udostępnili tę opcję dla prostej wygody. ..Czy to nie tylko polimorfizm?
Z mojego doświadczenia z Qt
tr()
iwtr()
metodami należy korzystać (tam, w Qt ) w lokalizacjiWidget
tekstu.Więc, wracając tekst niezmieniony ta metoda po prostu mówi:
Widget does no localization (translation of the text) by default. Override this function to enable your own logic
.źródło
Bardzo częstym przypadkiem jest „później dodana funkcjonalność”. Dlatego programista pomyślał, że może nastąpić zmiana tej funkcji później. Ponieważ uzyskujesz do niego dostęp jako funkcję, a nie jako sam parametr, możesz to łatwo globalnie zmienić. Powiedzmy, że masz indeks z:
a ponieważ indeks zaczyna się od 0, wszystko jest w porządku. Później zmienisz komponent gdzieś indziej, ten komponent wymaga przetłumaczenia indeksu, aby zacząć od 1. Trzeba by dodać setki indeksu + 1 wszędzie w kodzie. Ale przy użyciu takiej metody po prostu powiedz:
i wszystko w porządku. Takie funkcje mogą szybko doprowadzić do nadmiernej inżynierii, ale w niektórych momentach mają sens!
źródło
Takie funkcje pośredniczące są powszechne w sytuacjach dziedziczenia typu. Klasa podstawowa może nic nie robić, ale klasy pochodne mogą robić różne rzeczy z danymi wejściowymi. Deklaracja funkcji stub w klasie bazowej pozwala wszystkim klasom pochodnym mieć funkcję o tej nazwie, a poszczególne klasy pochodne zastępują ją bardziej skomplikowanym i użytecznym.
źródło
Jeden dodatkowy scenariusz jest podobny do użycia w Pythonie i C # właściwości, ale w językach, które nie mają tej funkcji.
Ogólnie rzecz biorąc, możesz zadeklarować coś jako tylko członka klasy; powiedzmy „nazwa” jako ciąg. Oznacza to, że uzyskujesz do niego dostęp w następujący sposób:
Później decydujesz, że nazwa naprawdę musi zależeć od tego, co znajduje się w obiekcie. To naprawdę powinna być funkcja. Ups! Nawet bez argumentów oznacza to, że cały kod, który ma do niego dostęp, musi zostać zmieniony na
Ale jeśli masz wiele takich wywołań, szanse na to, że coś pójdzie nie tak, są niewielkie - gdzieś ta zmiana nie zostanie wprowadzona, program się zawiesi, gdy dojdziesz do tego punktu itp.
Właściwości w C # / Python pozwalają zastąpić funkcję tym, co kiedyś było atrybutem, jednocześnie umożliwiając dostęp do niej jak do atrybutu, tj. Bez zmian. Nie musisz nawet planować z wyprzedzeniem.
Jeśli twój język tego nie ma, musisz planować z wyprzedzeniem, ale nadal możesz w pewien sposób wspierać go tak, jak robili to wcześniej ludzie, czyniąc z niego funkcję od samego początku, która nic nie robi. Na początku nie zrobi nic interesującego i wygląda na to, że powinien zostać usunięty, a wiele funkcji tego typu nigdy się nie zmienia. Ale później, jeśli zdasz sobie sprawę, że naprawdę za każdym razem, gdy dzwonisz
Widget.wtr
, musisz usunąć niektóre znaki specjalne, to nie jest wielka sprawa - to już funkcja, po prostu dodaj ją i gotowe.TL; DR To może być po prostu mądry programista planujący przyszłe zmiany.
źródło
print data
. Potem zdajesz sobie sprawę, że wszystkie ciągi muszą być pisane wielkimi literami - musisz znaleźć każdy wydruk w swoim programie i zmienić naprint data.upper()
. Ale jeśli maszdef cdata(data): return data
i wszędzie to mówiprint cdata(data)
, to po prostu zmieniasz się nadef cdata(data): return data.upper()
i to jest jedyna zmiana.Nie jest to bezużyteczne, w rzeczywistości może być niezwykle przydatne, ponieważ sprawia, że kod jest bardziej jednolity i elastyczny.
Powiedzmy na przykład, że masz listę osób i listę rozwijaną, z której użytkownik może wybrać, czy chcemy zobaczyć „wszystkich”, czy tylko tych, którzy są „mężczyznami” lub „kobietami”.
Możesz albo traktować „wszystko” jako szczególny przypadek, w którym to przypadku będziesz potrzebować dodatkowego, jeśli i jawnie sprawdzisz ten przypadek, albo możesz mieć funkcję filtrującą, która po prostu zwraca swój parametr (np. Pozwala na przejście wszystkiego), przypisany do użycia w przypadku „wszystkie”.
źródło
Filter
klasę lub interfejs zMaleFilter
iFemaleFilter
podklasy, a twój kod wymaga jakiegoś filtra, filtr, który nic nie robi (zwraca parametr bez zmian), jest tym, jak sobie radziszAll
. Funkcja nigdy nic nie robi, ale można ją zastąpić tą, która robi.