2014-10-06 104 views
28

行爲定義回調&協議定義了沒有簽名的方法。實施協議的模塊應給出所有這些方法的定義。對於使用行爲的模塊也是如此。什麼是語義差異?elixir中的協議和行爲之間的區別

我能想到的一個區別是,一個協議只能針對單一類型實現一次,因爲我們可以根據我們的要求多次實現模塊的行爲。我很清楚什麼時候該用什麼。除此之外是否還有其他區別?

+4

此外,最重要的是,行爲啓動新的進程,其中運行回調而協議功能在同一進程中運行。這與下面的評論相同,但經常被忽略。行爲隱藏了所有的併發和消息傳遞,但它們仍然存在,客戶端調用和回調調用在不同的進程中運行。 – rvirding 2014-10-09 00:16:00

+1

@rvirding我不知道它,我不記得在任何書或教程中看到。有沒有關於行爲如何隱式地啓動新流程的文檔或任何其他文章的任何部分? – 2016-04-15 10:01:37

+0

@KrzysztofWende它隱含在http://erlang.org/doc/design_principles/des_princ.html中。基本上,「行爲」一詞與OTP應用程序有很大的關係,因此也涉及監督樹木的維護過程。在Erlang中,一種行爲將常見模式(客戶端服務器,狀態機等)抽象出來,以便您不必手動調用spawn *和模式匹配消息(這很容易出錯)。弗雷德赫伯特的在線教程幫助我瞭解了很多:http://learnyousomeerlang.com/what-is-otp#the-common-process-abstracted – 2017-06-16 19:33:58

回答

30

協議是基於類型/數據的多態性。當我打電話給Enum.each(foo, ...)時,具體列舉由foo的類型確定。

行爲是一種無類型的插件機制。當我致電GenServer.start(MyModule)時,我明確地通過MyModule作爲插件,並且GenServer的通用代碼將在需要時調用此模塊。

+5

此外,最重要的是,行爲啓動新的進程,其中回調運行協議功能在相同的過程中運行。 – rvirding 2014-10-08 13:39:00

+6

@rvirding你錯了。行爲只是描述了模塊中必須存在的功能。他們對流程沒有做任何事情。 – rightfold 2015-05-24 23:15:48

+1

@rightfold ok,那麼elixir具有與erlang不同的行爲含義,這可能會讓人困惑,因爲它們也使用erlang行爲。你可以說erlang的行爲描述了接口函數,但是更多的是它的基礎,它們都是函數接口的進程的屬性。有進程就是erlang行爲的全部內容。 – rvirding 2015-05-26 11:12:43

13

通過JoséValim上同一主題的回答(從谷歌螺紋,https://groups.google.com/forum/#!msg/elixir-lang-talk/S0NlOoc4ThM/J2aD2hKrtuoJ

協議是確實是一個行爲+調度邏輯。

但是我認爲你錯過了行爲的要點。行爲 是非常有用的。例如,GenServer定義了一個行爲。 A 行爲是一種說法:給我一個模塊作爲參數,我會 對它調用以下回調,這些參數等等。 適用於除GenServer外的其他行爲的更復雜示例是Ecto 適配器。

但是,如果您有數據結構並且您希望 基於數據結構進行分派,則這不起作用。因此協議。