2014-10-06 14 views
28

Zachowania definiują wywołania zwrotne. & Protokoły definiują metody bez podpisów. Moduły implementujące protokół powinny dać definicję wszystkich tych metod. To samo dotyczy modułów używających zachowania. Jaka jest różnica semantyczna?Różnica między protokołem a zachowaniem w eliksirach

Jedna różnica polega na tym, że protokół może być zaimplementowany dla pojedynczego typu tylko raz, ponieważ możemy zaimplementować zachowanie dla modułu wiele razy w oparciu o nasze wymagania. Jasne jest, kiedy używać czego. Czy jest jakakolwiek inna różnica poza tym?

+4

Co więcej, zachowania uruchamiają nowe procesy, w których wywołania zwrotne są uruchamiane, podczas gdy funkcje protokołu działają w tym samym procesie. To jest ten sam komentarz co poniżej, ale często jest pomijany. Zachowania ukrywają wszystkie współbieżności i przekazywanie wiadomości, ale wciąż tam są, a wywołania klienta i wywołania zwrotne są uruchamiane w różnych procesach. – rvirding

+1

@rvirding Nie wiedziałem o tym i nie pamiętam tego w żadnej książce lub samouczku. Czy istnieje jakaś część dokumentacji lub inny artykuł na temat tego, w jaki sposób zachowania domyślnie uruchamiają nowe procesy? –

+0

@KrzysztofWende Jest to domyślnie podane w http://erlang.org/doc/design_principles/des_princ.html. Zasadniczo termin 'behaviour' jest głęboko związany z aplikacjami OTP, a więc z drzewami nadzoru, które dotyczą utrzymania procesów. W języku Erlang zachowanie usuwa abstrakcyjne wzorce (klient-serwer, automat stanowy itd.), Dzięki czemu nie trzeba ręcznie wywoływać komunikatów typu "spawn *" i wzorców (co jest podatne na błędy). Internetowy samouczek Freda Heberta bardzo mi pomógł, aby to zrozumieć: http://learnyousomeerlang.com/what-is-otp#the-common-process-abstracted –

Odpowiedz

30

Protokół jest polimorfizmem opartym na typie/danych. Kiedy dzwonię pod numer Enum.each(foo, ...), konkretne wyliczenie jest określane na podstawie typu foo.

Zachowanie jest bezimiennym mechanizmem wtyczek. Gdy zadzwonię pod numer GenServer.start(MyModule), jawnie przekazuję MyModule jako wtyczkę, a ogólny kod z GenServer wywoła ten moduł w razie potrzeby.

+5

Co więcej, zachowania uruchamiają nowe procesy, w których działają wywołania zwrotne, podczas gdy funkcje protokołu działają w tym samym procesie. – rvirding

+6

@rvirding Mylisz się. Zachowania opisują jedynie funkcje, które muszą być obecne w module. Nie robią nic z procesami. – rightfold

+1

@rightfold ok, a następnie eliksir ma inne znaczenie niż zachowanie w erlangu, co może być mylące, ponieważ również używają zachowań erlang. Można powiedzieć, że zachowanie erlang opisuje funkcje interfejsu, ale jest o wiele więcej, ponieważ podstawą są wszystkie właściwości procesów, z którymi funkcje łączą się. To, że są procesy, to wszystko, o co chodzi w erlangach. – rvirding

13

Odebrane przez Jose Valim na ten temat (z google nici https://groups.google.com/forum/#!msg/elixir-lang-talk/S0NlOoc4ThM/J2aD2hKrtuoJ)

Protokół rzeczywiście zachowanie + logiki przekazującego.

Jednak myślę, że brakuje wam punktu zachowań. Zachowania są niezwykle przydatne. Na przykład GenServer definiuje zachowanie. Zachowanie to jest sposobem na powiedzenie: daj mi moduł jako argument, a ja wezmę na siebie następujące wywołania zwrotne, które to argumenty i tak dalej. Bardziej złożonym przykładem zachowań poza GenServer są adaptery Ecto .

Jednak to nie działa, jeśli masz strukturę danych i chcesz, aby wysyłano w oparciu o strukturę danych. Stąd protokoły.