読者です 読者をやめる 読者になる 読者になる

Windows上で Rust を使用

Rust

今回は Windows 上で Rust を使ってみます。

Rust はトレイト・パターンマッチ・アトリビュート等のモダンな言語機能を持ち、オブジェクト指向と純粋関数型のプログラミングスタイルをサポートしている、なかなか興味深いプログラミング言語です。

Rust 1.0 以降は http://fits.hatenablog.com/entry/2015/09/20/193605 を参照

環境構築

まずは Rust のビルド・実行環境を構築します。
といっても下記を実施するだけです。

  • (1) Rust をインストール
  • (2) MinGWgcc をインストール

(2) に関しては、Haskell Platform 2013.2.0.0 for Windows 等をインストールしてあれば、その中に含まれている mingw を代わりに使えば良いので必要ありません。

また、Rust 0.9 では GCC に依存しているので (2) が必要となっていますが、将来的には変わるかもしれません。

(1) Rust をインストール

Using Rust on Windows の installer リンクから rust-0.9-install.exe をダウンロード、インストールします。

(2) MinGWgcc をインストール

http://sourceforge.net/projects/mingw/files/ から mingw-get-setup.exe をダウンロード、インストールします。

also install support for the graphical user interface のチェックを外してインストールした場合、「Quit」 ボタンを押下してインストールを終了する点にご注意ください。(この場合 「Continue」 ボタンは有効になりません)

次に MinGWgcc をインストールします。

コマンドラインでインストールする場合、mingw-get.exe (例 C:\MinGW\bin\mingw-get.exe) を使って gcc をインストールします。

MinGWgcc をインストール
> mingw-get install gcc

なお、Haskell Platform 2013.2.0.0 for Windows 等をインストールしてあれば、MinGW のインストールは不要です。

ビルドと実行

それでは下記のようなサンプルソースをビルドして実行してみます。

実行時の処理は main() 関数へ実装します。

sample.rs
fn main() {
    let d1 = Data { name: ~"data", value: 10 };
    let d2 = Data { name: ~"data", value: 10 };
    let d3 = Data { name: ~"data", value:  0 };
    let d4 = Data { name: ~"etc",  value:  5 };

    println!("d1 == d2 : {}", d1 == d2);
    println!("d1 == d2 : {}", d1.eq(&d2));
    println!("d1 == d3 : {}", d1 == d3);

    println!("-----")

    println!("{:?}", d1);
    println!("{}", d1.to_str());

    println!("-----")

    println!("times = {}", d1.times(3));

    println!("-----")

    d1.printValue();
    d3.printValue();

    println!("-----")

    let res = calc([d1, d2, d3, d4]);
    println!("calc = {}", res);
}

fn calc(list: &[Data]) -> int {
    list.iter().fold(1, |acc, v| acc * match v {
        // name = "data" で value の値が 0 より大きい場合
        &Data {name: ~"data", value: b} if b > 0 => b,
        // それ以外
        _ => 1
    })
}

// Eq と ToStr トレイトを自動導出した struct 型の定義
#[deriving(Eq, ToStr)]
struct Data {
    name: ~str,
    value: int
}

// Data のメソッド定義と実装
impl Data {
    fn printValue(&self) {
        match self.value {
            0 => println!("value: zero"),
            a @ _ => println!("value: {}", a)
        }
    }
}

// トレイト定義
trait Sample {
    fn get_value(&self) -> int;

    fn times(&self, n: int) -> int {
        self.get_value() * n
    }
}

// Data へ Sample トレイトを実装
impl Sample for Data {
    fn get_value(&self) -> int {
        self.value
    }
}

上記では deriving アトリビュートを使って Eq と ToStr トレイトを自動導出しています。 Eq の deriving で eq() メソッドが自動的に実装され == が使えるようになり、ToStr の deriving で to_str() メソッドが自動的に実装されます。

なお、struct 型(構造体)は {} で出力できないので、代わりに {:?} を使うか std::fmt::Default トレイトを実装する必要があります。

ちなみに、~ はポインタ(Owning pointers) で & はリファレンスです。

ビルド

まずは環境変数 PATH へ Rust と MinGW の bin ディレクトリのパスを設定しておきます。

環境変数 PATH の設定例1
set PATH=C:\Rust\bin;C:\MinGW\bin

MinGW の代わりに Haskell Platform 2013.2.0.0 for Windows を使う場合は下記のようになります。

環境変数 PATH の設定例2
set PATH=C:\Rust\bin;C:\Haskell Platform\2013.2.0.0\mingw\bin

rustc コマンドを使ってビルドを実施します。 ビルドに成功すると .exe ファイルが作成されます。

ビルド例
> rustc sample.rs

実行

ビルドで生成された .exe ファイルを実行します。

実行には Rust の bin ディレクトリ内の .dll ファイルを使いますので、Rust の bin は環境変数 PATH へ設定しておく必要があります。 (MinGW は基本的に不要です)

実行例
> sample.exe
d1 == d2 : true
d1 == d2 : true
d1 == d3 : false
-----
Data{name: ~"data", value: 10}
Data{name: data, value: 10}
-----
times = 30
-----
value: 10
value: zero
-----
calc = 100

今回使用したサンプルソースhttp://github.com/fits/try_samples/tree/master/blog/20140223/