Crystalとは
Ruby言語と似た構文を持った、静的型付けができる言語です。
Crystalの目標
・構文がRubyの影響を受けている。(ほぼRuby言語の構文)
・静的な型のチェックがあるが、変数とメソッドの引数の型を指定しなくてもよい。
・Crystalのルールに基づいて書かれたC言語のコードを呼び出すことができる。
・ボイラープレートコード(定型文)を避けるため、コンパイル時間評価とコード生成を持つ。
・効率的なネイティブコードにコンパイルしてくれる。
記事を書いた理由
公式リファレンスを読んだところ、Crystal特有の構文に加えてRuby言語ではおなじみの構文もしっかり書いてありました。
そこで今回は翻訳も含めてCrystal特有の構文や型指定方法に注目して記述していきます。
公式サイト
http://crystal-lang.org
公式リファレンス
http://crystal-lang.org/docs/index.html
導入
・OS OSX Yosemite 10.10.3
・Homebrewを使用
・Crystal 0.7.4
$ brew tap manastech/crystal
$ brew install crystal
コンパイル&実行
$ crystal helloworld.cy
環境を構築しなくてもこちらで実行することができます。
http://play.crystal-lang.org/#/cr
文法
変数型宣言
str :: String
str = "Hello"
変数名 :: 型名
で変数に型を指定することができます。
str :: String = "Hello"
#unexpected token: =
型指定と代入を同時に行うことができない?(調査不足の可能性あり)
返却値型
def hello : String
"hello"
end
def メソッド名 : 型名
end
で返却値型を指定できます。
もし、型が違うと
def hello : String
1
end
#in line 1: type must be String, not Int32
しっかりとエラーを吐いてくれます。
引数型
def hello(keyword : String)
"hello #{keyword}"
end
hello("world") #"hello world"
def メソッド名(引数名 : 型名)
end
で引数の型を指定できます。
Crystal標準で扱える型
- Nil
- Bool
- Integers(Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64)
- Floats(Float32, Float64)
- Char
- String
- Array
- Hash
- Range
- Regex
- Tuple
- Proc
Nill
nilオブジェクトに対応した型です。
Bool
true、falseオブジェクトに対応した型です。
Integers
整数型に関してはInt8、Int16、Int32、Int64があり、それぞれビット数に対応しています。
加えて、符号無し整数 UInt8, UInt16, UInt32, UInt64もあります。
基本的にはInt32を使用することになります。
num :: Int32
num = 10
Floats
浮動小数点型は2種類存在しておりFloat32、Float64となります。
整数型と同じくビット数に対応しています。
基本的にはFloat64を使用することになります。
f :: Float64
f = 0.1
String
文字列型です。
str :: String
str = "str"
Array
可変長配列型です。
配列で扱う型を指定することができます。
array :: Array(Int32)
array = [1, 2, 3]
型を複数指定することも可能です。
array :: Array(Int32|String)
array = [1, "a"]
以下の方法でも初期化できます。
array = [] of Int32
#Array(Int32).newと同等
Hash
hash型です。
key,valueの型を指定することができます。
hash :: Hash(Int32, String) #key: Int32 , value: String
hash = {1 => "a", 2 => "b"}
型を複数指定することもできます
hash :: Hash(Int32, String|Char)
hash = {1 => "a", 2 => 'c'}
以下の方法でも初期化できます。
hash = {} of Int32 => String
#hash = Hash(Int32, String).new と同等
#key: Int32, value: String
Range
範囲型です。
型の指定は以下の形式です。
range :: Range(Int32, Int32)
range = 1..2
Regex
正規表現型です。
reg :: Regex
reg = /foo|bar/
Tuple
タプル型です。
型の指定は以下の形式です。
tuple :: Tuple(Int32, String, Char)
tuple = {1, "a", 'a'}
Proc
Proc型はrubyにおけるProcと同じですが、記法が若干異なります
y :: Proc(Int32, String)
y = ->(x : Int32) { x.to_s }
puts y.call(1) #"1"
Proc(引数型, 返却値型)のように指定することができます。
proc :: Proc(Int32)
proc = ->{ 1 }
proc.call #1
引数がないprocの場合はProc(返却値型)です。
メソッドをprocで実行する場合。
def plus_one(x)
x + 1
end
proc = ->plus_one(Int32)
proc.call(41) #=> 42
まとめ
今回はRuby言語と異なる部分に注目して記述しました。
今回Crystalに触れてみて感じたこと
- ほとんどの記述方法がRubyなので馴染みやすい。
- Rubyの記法で静的型付けの記述ができるのは有用性がありそう。(純粋なオブジェクト指向という観点で比較すると、Rubyよりしっかり書きたいがScalaよりは緩く書きたいときなど)
- Rubyに存在していた記法で無くなってしまったものがある?。(for文が見当たらなかった)
- 少々改善できそうな部分がある?変数の型指定と代入が同時に行えないなど。(調査不足の可能性あり)
まだバージョン1.0に達していないので今後に期待です。
紹介していない記法などもありますので今後もCrystalに関して記事を書いていこうかと思います。