LoginSignup
24
24

More than 5 years have passed since last update.

Rubyの構文で静的型付けな記述ができる言語、Crystalの導入から型指定方法 まとめ

Last updated at Posted at 2015-07-13

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に関して記事を書いていこうかと思います。

24
24
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
24
24