7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ClojureのProtocol

Posted at

Clojureのdefprotocolについて調べてみた。Javaでいうインターフェースのようなものなんだけど、Clojureは動的型の言語なので、インターフェース(のようなもの)があることで、何がよいのか、というのが今回のテーマです。
まずは使ってみるところから。

Protoclの定義

(defprotocol Hoge
  (foo [this])
  (bar [this a b]))

これで、defprotocolを呼び出したネームスペースにfooという関数とbarという関数が定義されます。(ns-internsで確認できます。)

protocolの実装

このプロトコルに対する実装を与えるコードは以下のようになります。

(defrecord Hoge1 []
  Hoge
  (foo [this] "this is Hoge 1")
  (bar [this a b] (str a b)))

(defrecord Hoge2 []
  Hoge
  (foo [this] "this is Hoge 2")
  (bar [this a b] (str b a)))

関数を実行すると以下のようになります。

(foo (Hoge1.))
=> "this is Hoge1"

(foo (Hoge2.))
"this is Hoge2"

(bar (Hoge1.) "a" "b")
=> "ab"

(bar (Hoge2.) "a" "b")
=> "ba"

プロトコルを通じて、fooやbarという同一のネームスペース・名前の関数に多態性(第一引数のインスタンスによって関数の振る舞いが変わる)が与えられたのがわかると思います。

protocolの作成単位

protocolは標準実装を定義することはできないので、一つのプロトコルに沢山の関数を用意すると、レコードを一つ作るたびに実装を行うコードを書かなければいけません。
このため、1つのプロトコルに用意する関数は少なくしたほうが、分かり切った実装を何度も書かなくて済むようになります。

参考文献

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?