Nimでオブジェクト指向する
先日Nimでオブジェクト指向っぽいコードを書いたのですが、まとまってる記事などが見当たらなかったので軽いまとめです。
内容の高度さで言えば
class Greeting { fun printHello(s: String) { println("Hello, $s") } } fun main() { val greeting = Greeting() greeting.printHello("World") // > Hello, World }
くらいのことしか言わないので知ってるよって人は読まないで大丈夫です。
※編集後追記:公式以上のことは書いてないのでもう公式を読めばいいんじゃないかな*1
クラス(っぽいもの)を作る
Nimにはクラスの概念がないのですが、構造体を利用してクラスっぽいものを作ることができます。
日本語だと下2つの記事がまとまってると感じたので是非見てみてください。
公式がよければ公式ではNim Tutorial (Part Ⅱ)にて説明されています。
公式では説明されているのですが、記事でやたら継承されているRootObj
とはなんぞやということですが、Nimでは何も継承していないobjectはfinal
として扱われるので、そのobjectを継承した別のobjectを作りたい場合はRootObj
を継承しようね、というものであり、それ以上のことは何もないようです。
メソッド(っぽいもの)を作る
「え、お前クラスの説明してないじゃん」と言われたらごめんなさいですけど、クラスについては公式、または英語がキツいと感じても上で示した2つの記事を読めばだいたい大丈夫だと思うので、ここからはメソッドについて書きたいと思います。
むしろクラスの作り方についてはまとまってるものがあったのですが、メソッドについてまとめられたものが見当たらなかったので書きたいことはここからです。
上で示したQiitaや公式にもある通り、Nimではクラスはなく、あくまで構造体をクラスっぽく扱えるのでクラスのメンバ関数はありません。*2
その代わり、関数proc sum(a: int, b: int) : int = a + b
をsum(1, 2)
または1.sum(2)
のように書くことができます。
ちょっと例が微妙ですが説明すると、関数を呼び出す際に、その関数を第一引数の型のメソッドのように扱えるので、これを利用してメソッドっぽいものが作れます。
Nim公式によると、クラスにメソッドを追加できなくすることによって
- メソッドがどのクラスに所属しているかいちいち気にする必要がなくなる
- 上の
1.sum(2)
のように既存のクラスや外部のクラスにもメソッドを追加したっぽくできるようになる
の2点のメリットがあるとのことです。2点目はKotlinの拡張関数みたいで確かになかなか素敵に使えました。
関数の宣言
Nimで関数の宣言に使うキーワードにはproc
とmethod
、func
の三種類があります。
まず、method
は引数にobjectを取らなければならない制約があるので、これは言葉の通りメソッドとして使うことが前提とされているような気がします。
staticメソッドが欲しかったらproc
で宣言する必要がありそうです。
次に、proc
は引数の型がコンパイル時に決定されるのに対し、method
キーワードを使うとそれらが動的に決定されます。
ものすごくざっくりと言うとポリモフィズムを適用したかったらmethod
を使おうね、ということだと僕は解釈しました。
また、どうやらmethod
ではproc
で効く最適化が一部効かなくなるようです。
func
は大体の部分がproc
と同じですが、副作用のない関数であることを保証するキーワードになっています。
Nimのややマイナーな言語仕様(funcとnot nil) - Qiita
まとめ
ここまでの内容で、冒頭で出したようなやり方でHello, Worldを出すことができるかと思います。
type Greeting = ref object # base methodにしないとWarningが出て気持ち悪かったので{.base.} method printHello(greeting: Greeting, s: string) {.base.} = echo "Hell, " & s # Nimではmainメソッドはないのでトップレベルに書いた処理が実行される when isMainModule: let greeting = Greeting() greeting.printHello("World")
できた。
あとはお好みでpragma
を。下の記事が詳しいです。これはあまり公式に書いてなくてつらい、、*3
ちなみに僕がNimでオブジェクト指向してみたのはなんとなく作ったライフゲームですので、参考になるかはわかりませんがもしよければ。