前回の記事にて……
前回の記事で、Nimはversion1までは様子見すると言って、のんびり構えていたら、もうリリースされてしまいました。ということで、これからNimを始めようという方のために、まだまだ日本語の情報が少ないので、大まかな使い方や仕様を書いていこうかと思います。Nimはガベージコレクタ・型推論付きのコンパイラ言語で、たとえばHello worldプログラムを作ってやってみます。
---------
hello.nim
---------
echo "Hello, world"
一行だけのプログラムですが、ちゃんと出力します。
$ nim c -r hello.nim
.
.
.いろいろ表示される
.
Hello, world
この場合、.cache
ディレクトリ(私の場合)にhello.nim.c
hello.nim.c.o
とその他諸々のファイルが作成されます。そして、作業中のディレクトリには実行ファイルhello
が作成されます。
$ ls
hello hello.nim
$ ./hello
Hello, world
一見すごくシンプルな言語に見えますが、実は結構難しい言語なのではないかと、個人的には思っています。Nimの大まかな文法
変数
型については公式ドキュメントを読むことをおすすめします。と言いますのは、基本型は大体どの言語も大体同じ感じなのですが、Nimの場合、関数の仮引数に使用可能な型やreturnの時に使える型やマクロ作成時に使える型など特別なときにのみ使用できる型も存在するからです。少しややこしい。さて変数宣言についてですが、こちらも2種類存在します。
let
とvar
です。前者はイミュータブルつまり変更不可。後者はミュータブルつまり変更可。したがってlet
で宣言した変数に値を代入しようとするとエラーになります。
let x: int = 3
x = 5 # ERROR!!
var y: int = 3
y = 5 # OK!!
関数
関数は意外とややこしいです。resultという特別な変数があったり、discardという戻り値を破棄するものがあったりします。関数を定義する際も2種類(おまけ的に)あります。
proc
とfunc
です。func
は割と最近導入されたもので、副作用を許さない関数です。例えば以下のような副作用のある関数でfunc
を使うとエラーになります。
func hello() =
echo "Hello"
hello() # ERROR
これは以前まで以下のようにプラグマを使って、書いていました。
proc hello() {.noSideEffect.} =
echo "Hello"
hello() # ERROR
コンパイルの際に副作用の有無を確認できるという感じです。構造体・列挙型
Nimではtype
を使って定義します。
type
Person = object
name, email: string
var p: Person
p = Person(name: "Nim", email: "nim@nim.com")
echo p # (name: "Nim", email: "nim@nim.com")
しかし上記のやり方だとメモリ効率がよろしくない(スタック領域を使う)ので、以下のような参照型を使ったやり方(ヒープ領域を使う)が一般的なようです。
type
Person = ref object
name, email: string
var p: Person = new Person
p = Person(name: "Nim", email: "nim@nim.com")
echo p.name, ", ", p.email # Nim, nim@nim.com
列挙型もまたtype
を使います。
type
MyEnum = enum
A, B, C
var a = MyEnum.A
echo a # A
ここで{.pure.}
プラグマを使うことができるのですが、使っても使わなくてもさして変化が分からない。ちょっと疑問。違いの分かる方、ぜひ教えて下さい。条件分岐
条件分岐はif~elif~else
およびcase~of~else
があり、これは以下のような書き方になります。
var x = 30
if x.mod(15) == 0:
echo "FizzBuzz"
elif x.mod(5) == 0:
echo "Buzz"
elif x.mod(3) == 0:
echo "Fizz"
else:
echo $x
var x = 'A'
case x:
of 'A': echo true
else: echo false
反復
反復処理にはwhile
やfor
があります。
var x = 0
while x < 10:
echo x
x.inc()
for i in 0 ..< 10:
echo i
defer
Nimにはdefer
というものがあります。いわゆるtry~except~finally
のfinally
の部分と同じです。使い方は簡単。
block:
defer: echo "finish"
echo "start"
-------
出力結果
-------
start
finish
defer
はトップレベルでは使えないので、block
を使っています。block
はラベルをつけることもできます。
block deferExample:
defer: echo "finish"
echo "start"