最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

多型: Protocol

XAMPP下载 admin 875浏览 0评论
 雖然我也很想趕快發個感想文結業,但是題目講不完只好再寫一篇。這一篇想來示範所謂的新的角度看程式的一個例子,就是不需要封裝與繼承,還是可以有多型這回事。

一點點理論
多形 (polymorphism) 在學術上,分為參數多型 (parametric polymorphism) 及特設多型 (ad-hoc polymorphism)。參數多型適用於靜態型別的語言,例如 Haskell、OCaml 等等,物件導向的 Java、C# 則是透過泛型來實作。因為 Elixir 是動態型別語言,所以基本上不適用。

而特設多型還分成 close ad-hoc polymorphism 及 open ad-hoc polymorphism。前者在 Elixir 中,就是函式的 pattern matching。而 open ad-hoc polymorphism,就是今天所要講的 Protocol。

實作
多型具體講起來,就是依資料型別 (物件型別) 的不同,會有不一樣的行為。回想一下 Enum 模組,像是 Enum.map/2、Enum.reduce/3,第一個參數可以使用各種型別的集合,這些函式都能正確的遍歷每個集合。這就是使用了 Protocol 機制達成的。

例如我們想要實作一個 Find.next/1 函式,會依不同的型別找到下一個值,首先要先宣告一個 Protocol:

defprotocol Find do
def next(data)
end
defprotocol 後面接模組名稱,並在 do…end 區塊裡放入這個 protocol 所擁有的函式名稱及參數,這些函式沒有本體。如果你會寫 Java 的話,可以想像它有點像是 Interface。

而不同型別要實作此 protocol 時,要使用 defimpl:

defimpl Find, for: Integer do
def next(i), do: i + 1
end

defimpl Find, for: BitString do
def next(str) do
str
|> String.to_charlist
|> Enum.map(&(&1 + 1))
|> List.to_string
end
end
這些 defimpl 若是內建型別,習慣上會放在跟 defprotocol 同一個檔案裡。而若是自訂的 struct 的話,則會放在宣告 struct 的檔案下。

這麼一來,Find.next/1 就會依傳入的型別不同,進行不同的動作了:

iex> Find.next(1)
2
iex> Find.next(“a”)
“b”
iex> Find.next(“abc”)
“bcd”
所有的型別: Any
如果想要實作對其它所有的型別 protocol 的話,可以使用 For: Any:

defimpl Next, for: Any do
def next(_), do: :error
end
下一篇就是感想文了。Happy hacking!

转载请注明:XAMPP中文组官网 » 多型: Protocol

您必须 登录 才能发表评论!