rustメモ
rustupを用いたrustコンパイラツールのインストール
以下のURLからインストーラをダウンロードする。
以下のように、binをPATHに追加する。
source $HOME/.cargo/env
- インストールされるツール
- cargo
- rustc
- rustdoc
新規プロジェクトの作成
以下のようにプロジェクト(e.g. hello)を作成する。
$ cargo new --bin hello
ビルドする。
$ cargo run
標準ライブラリのドキュメントを見る
$ rustup doc --std
crate(依存ライブラリ)のドキュメントを見る
以下のコマンドを実行すると、ドキュメントがプロジェクトのtarget配下にダウンロードされ、ブラウザで開かれる。
crateの例: iron
$ cargo doc -p iron --open
rust言語についてのメモ
- 関数 fn get_form(_request: &mut Request) -> IronResult
{ ... } // 仮引数: 型、&は参照?、->の後ろは戻り値の型 - 変数名を_で始めることでこの変数を使わないことをコンパイラに教える
- ローカル変数 let mut var = xxx; // mutはmutableのこと?
- raw string構文 r#\"...\"# ダブルクォートをエスケープなしで使える
- 関数bodyの最後の式が暗黙に関数の戻り値になる。(注意: セミコロンをつけてはならない)
おまけ ASTダンプ
ASTダンプは、nightly rustでないとできないので、以下のように--channel=nightlyを指定してインストール
$ sh rustup.sh --prefix=/home/xxx/rust_nightly --channel=nightly
ASTダンプコマンド
$ rustc -Z ast-json main.rs
入力ファイル
fn main() { println!("Hello, world!"); }
以下のASTが出力されたが、よくわからない。
{ "module": { "inner": { "lo": 0, "hi": 44 }, "items": [ { "ident": "", "attrs": [ { "id": { "_field0": 1 }, "style": "Outer", "path": { "span": { "lo": 0, "hi": 0 }, "segments": [ { "ident": "prelude_import", "args": null } ] }, "tokens": [], "is_sugared_doc": false, "span": { "lo": 0, "hi": 0 } } ], "id": 2, "node": { "variant": "Use", "fields": [ { "prefix": { "span": { "lo": 0, "hi": 0 }, "segments": [ { "ident": "{{root}}", "args": null }, { "ident": "std", "args": null }, { "ident": "prelude", "args": null }, { "ident": "v1", "args": null } ] }, "kind": "Glob", "span": { "lo": 0, "hi": 0 } } ] }, "vis": { "node": "Inherited", "span": { "lo": 0, "hi": 0 } }, "span": { "lo": 0, "hi": 0 }, "tokens": null }, { "ident": "std", "attrs": [ { "id": { "_field0": 0 }, "style": "Outer", "path": { "span": { "lo": 0, "hi": 0 }, "segments": [ { "ident": "macro_use", "args": null } ] }, "tokens": [], "is_sugared_doc": false, "span": { "lo": 0, "hi": 0 } } ], "id": 3, "node": { "variant": "ExternCrate", "fields": [ null ] }, "vis": { "node": "Inherited", "span": { "lo": 0, "hi": 0 } }, "span": { "lo": 0, "hi": 0 }, "tokens": null }, { "ident": "main", "attrs": [], "id": 4, "node": { "variant": "Fn", "fields": [ { "inputs": [], "output": { "variant": "Default", "fields": [ { "lo": 10, "hi": 10 } ] }, "variadic": false }, { "unsafety": "Normal", "asyncness": "NotAsync", "constness": { "node": "NotConst", "span": { "lo": 0, "hi": 2 } }, "abi": "Rust" }, { "params": [], "where_clause": { "id": 5, "predicates": [], "span": { "lo": 0, "hi": 0 } }, "span": { "lo": 0, "hi": 0 } }, { "stmts": [ { "id": 22, "node": { "variant": "Semi", "fields": [ { "id": 10, "node": { "variant": "Block", "fields": [ { "stmts": [ { "id": 21, "node": { "variant": "Semi", "fields": [ { "id": 9, "node": { "variant": "Call", "fields": [ { "id": 8, "node": { "variant": "Path", "fields": [ null, { "span": { "lo": 7767836, "hi": 7767859 }, "segments": [ { "ident": "$crate", "args": null }, { "ident": "io", "args": null }, { "ident": "_print", "args": null } ] } ] }, "span": { "lo": 7767836, "hi": 7767859 }, "attrs": { "_field0": null } }, [ { "id": 20, "node": { "variant": "Call", "fields": [ { "id": 11, "node": { "variant": "Path", "fields": [ null, { "span": { "lo": 7767862, "hi": 7767896 }, "segments": [ { "ident": "$crate", "args": null }, { "ident": "fmt", "args": null }, { "ident": "Arguments", "args": null }, { "ident": "new_v1", "args": null } ] } ] }, "span": { "lo": 7767862, "hi": 7767896 }, "attrs": { "_field0": null } }, [ { "id": 14, "node": { "variant": "AddrOf", "fields": [ "Immutable", { "id": 13, "node": { "variant": "Array", "fields": [ [ { "id": 12, "node": { "variant": "Lit", "fields": [ { "node": { "variant": "Str", "fields": [ "Hello, world!\n", "Cooked" ] }, "span": { "lo": 25, "hi": 40 } } ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } } ] ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } } ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } }, { "id": 19, "node": { "variant": "AddrOf", "fields": [ "Immutable", { "id": 18, "node": { "variant": "Match", "fields": [ { "id": 15, "node": { "variant": "Tup", "fields": [ [] ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } }, [ { "attrs": [], "pats": [ { "id": 16, "node": { "variant": "Tuple", "fields": [ [], null ] }, "span": { "lo": 25, "hi": 40 } } ], "guard": null, "body": { "id": 17, "node": { "variant": "Array", "fields": [ [] ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } } } ] ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } } ] }, "span": { "lo": 25, "hi": 40 }, "attrs": { "_field0": null } } ] ] }, "span": { "lo": 7767862, "hi": 7767896 }, "attrs": { "_field0": null } } ] ] }, "span": { "lo": 7767836, "hi": 7767898 }, "attrs": { "_field0": null } } ] }, "span": { "lo": 7767836, "hi": 7767900 } } ], "id": 7, "rules": "Default", "span": { "lo": 7767834, "hi": 7767902 }, "recovered": false }, null ] }, "span": { "lo": 7767834, "hi": 7767902 }, "attrs": { "_field0": null } } ] }, "span": { "lo": 7767834, "hi": 7767902 } } ], "id": 6, "rules": "Default", "span": { "lo": 10, "hi": 44 }, "recovered": false } ] }, "vis": { "node": "Inherited", "span": { "lo": 0, "hi": 0 } }, "span": { "lo": 0, "hi": 44 }, "tokens": [ { "variant": "Token", "fields": [ { "lo": 0, "hi": 2 }, { "variant": "Ident", "fields": [ "fn", false ] } ] }, { "variant": "Token", "fields": [ { "lo": 3, "hi": 7 }, { "variant": "Ident", "fields": [ "main", false ] } ] }, { "variant": "Delimited", "fields": [ { "lo": 7, "hi": 9 }, { "delim": "Paren", "tts": [] } ] }, { "variant": "Delimited", "fields": [ { "lo": 10, "hi": 44 }, { "delim": "Brace", "tts": [ { "variant": "Token", "fields": [ { "lo": 16, "hi": 23 }, { "variant": "Ident", "fields": [ "println", false ] } ] }, { "variant": "Token", "fields": [ { "lo": 23, "hi": 24 }, "Not" ] }, { "variant": "Delimited", "fields": [ { "lo": 24, "hi": 41 }, { "delim": "Paren", "tts": [ { "variant": "Token", "fields": [ { "lo": 25, "hi": 40 }, { "variant": "Literal", "fields": [ { "variant": "Str_", "fields": [ "Hello, world!" ] }, null ] } ] } ] } ] }, { "variant": "Token", "fields": [ { "lo": 41, "hi": 42 }, "Semi" ] } ] } ] } ] } ] }, "attrs": [], "span": { "lo": 0, "hi": 44 } }
TensorFlowをインストールしてみた
今さらですが、TensorFlowをインストールしてみました。
pipのインストール
$ sudo pacman -S pip
TensorFlow 1.5のインストール
1.9だとillegal instruction (core dumped)になってしまったので1.5を指定しました。
$ pip install tensorflow=1.5 --user
ちなみに--userはローカルインストールするためのオプションです。
次のようにして、インストールパスが確認できます。
$ pip show [パッケージ名]
動作確認
$ python Python 3.6.4 (default, Jan 5 2018, 02:35:40) [GCC 7.2.1 20171224] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow as tf >>> hello = tf.constant('Hello, TensorFlow!') >>> sess = tf.Session() 2018-04-19 21:12:12.121902: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 >>> print(sess.run(hello)) b'Hello, TensorFlow!'
リソースの解放忘れを防ぐには? Effective C++ 14項を読んで
Scott Mayers著, 小林健一郎訳, Effective C++ 第3版, 丸善出版(2014) を1日1項目読んでいます。
今日は14項を読みました。
リソース(メモリ、ファイルディスクリプタ、ミューテックスロック、DB接続、ネットワークソケットなど)の解放忘れを防ぐにはどうしたらよいでしょうか? RAIIオブジェクトをリソースを渡すことで生成すればよい。そして、RAIIオブジェクトとしては、C++11のstd::shared_ptrを使うとよい、ということがわかりました。
どうして、リソースの解放忘れが起こるのでしょうか? それは、例えば、リソースとしてメモリを考えると、ある関数内でヒープ領域にメモリを確保すると、その関数を抜ける前に、メモリを解放する必要があります。
void f(){ A* a = new A(); ... // ここで、returnしたり、例外が発生したりするとdeleteが実行されない。 delete a; }
しかし、上のように、deleteする前にreturnしたり、例外が発生したりするとdeleteが実行されず、メモリリークになります。何らかの理由で関数を抜ける際に、必ずdeleteが実行されるような仕組みはないでしょうか? これを解決するアイディアはデストラクタです。
デストラクタは、そのオブジェクトの寿命が終わると実行されます。つまり、関数内で、あるオブジェクトをポインタなどのリソースを渡すことで生成すれば、関数を抜けるときに、オブジェクトのデストラクタが実行されるので、このデストラクタでポインタをdeleteしてもらうことができます。
このデストラクタをもつオブジェクトのことをRAIIオブジェクトといいます。既に用意されているRAIIオブジェクトとして、C++11のstd::shared_ptrがあります。また、std::shared_ptrをstaticでないメンバとしてもつオブジェクトもRAIIオブジェクトになります。なぜなら、デストラクタが呼ばれるとき、メンバのデストラクタも呼ばれるからです。
リソースがメモリのときには、リソースへのポインタをstd::shared_ptrのコンストラクタに渡します。すると、std::shared_ptrのデストラクタでこのポインタがdeleteされます。(delete[]でないことに注意)
リソースがメモリでないときには、リソースへのポインタをdeleteするとともに、何らかの解放処理(デリータ)が必要になります。リソースへのポインタを引数とする関数オブジェクト、すなわちデリータをstd::shared_ptrのコンストラクタに渡せます。
リソースがミューテックスロックの場合のサンプル
#include <memory> #include <iostream> class Mutex { public: void lock(){ std::cout << "locked\n"; } void unlock(){ std::cout << "unlocked\n"; } }; void lock(Mutex* pm){ pm->lock(); } void unlock(Mutex* pm){ pm->unlock(); } class Lock { public: Lock(Mutex* pm) : mutexPtr(pm, unlock) { lock(mutexPtr.get()); } ~Lock(){} private: std::shared_ptr<Mutex> mutexPtr; }; void test(const Lock& ml){ std::cout << "test start\n"; { Lock ml2(ml); std::cout << "in critical session in test...\n"; } std::cout << "test end\n"; } int main(int argc, char* argv[]){ Mutex m; std::cout << "start\n"; { Lock ml1(&m); std::cout << "in critical session...\n"; test(ml1); } std::cout << "end\n"; return 0; }
$ clang++ -std=c++11 Lock.cpp -o lock
実行
$ ./lock start locked in critical session... test start in critical session in test... test end unlocked end
Scott Mayersさんのブログhttp://scottmeyers.blogspot.jp/も読んでみようと思います。
国立近代美術館 熊谷守一展覧会
奥さんと一緒に国立近代美術館の熊谷守一没後40年の回顧展に行ってきた。
東京駅の丸善が入っているオアゾがある出口から出て、徒歩で東京メトロ大手町駅に行った。
大手町からは、東西線で竹橋まで一駅だ。
東西線に乗る前に、地下のドトールで軽く食べた。
奥さんは、レタスドッグと黒ごまのマシュマロラテを注文し、
僕は、チーズのパンとオレンジジュースを頼んだ。
奥さんは、レタスドッグのソーセージをマシュマロラテに沈没させていた。
熊谷守一は、わりと好きな画家だ。
知っていたとおり、抽象化された、動物や風景の絵が多かった。
一見すると何の絵なのかわからないほど抽象化された絵の方が、
絵本のようにわかりやすくデフォルメされたものよりも、
より高尚な感じがしてよいと思った。
例えば、熊谷がシベリアで見たという乾いたような茶色い風景の中央に
赤や緑、白といった色の布のようなものが墓標のように描かれている
絵があった。
また、地味な茶色の画面で、ピンク色の亀が水から人間のペニスのように
顔をだしている絵や、これまた、おなじみの、茶色の画面で、
カッターで短く切れ込みをズッズッズッと入れたような
一本線の小魚の小群が泳いでいた。
そんな絵をずらずらと眺めた後、MOMATコレクションを見た。
ロバート・フランクの写真「青い空」に感動した。
モノクロ写真で窓の中の花を撮ったもので、その窓に
雲が写っていた。
また、チンポムのカラスが後ろから追っかけてくる映像作品が
とても印象的だった。
www.youtube.com
おもしろそうなホームページ
圏論について書いてある。絵が面白いな。
www.geocities.jp