タグ

ブックマーク / qnighy.hatenablog.com (10)

  • Rustのモジュールを詳細に理解する(1) モジュール入門 (この回は簡単です!) - 簡潔なQ

    概要: Rust2018以降、Rustのモジュールシステムは入門しやすく、かつマスターしにくくなりました。そこで記事では、その両方を達成することを目指しました。 モジュール入門 名前解決の役割と用語 モジュールグラフの構造 インポート解決 可視性 パス解決 名前解決とマクロ 記事は2017年に書いた記事 (https://qnighy.hatenablog.com/entry/2017/03/27/070000, https://qnighy.hatenablog.com/entry/2017/04/24/070000 ) と同じテーマで、Rust2018を考慮して改めてまとめ直したものです。 モジュールとは モジュールはRustのプログラムを分割する単位のひとつです。ワークスペース・クレート・モジュールという単位になっていると考えてください。 ワークスペースは関連するライブラリ(クレ

    Rustのモジュールを詳細に理解する(1) モジュール入門 (この回は簡単です!) - 簡潔なQ
    clavier
    clavier 2019/05/07
  • Rustのパニック機構 - 簡潔なQ

    概要: Rustのパニック機構は異常終了の処理を安全に行うためにある。この動作を詳しくみていく。 パニックとは何か Rustには2つの異なる例外処理機構があります。 発生源 対処方法 例 パニック プログラミングエラー 原則として捕捉しない assert!() 境界外参照 Result 例外的な入力 必要に応じて捕捉 I/Oエラー (File::read) パースエラー (str::parse) パニックとResultの関係についてはTRPL第2版第9章、未定義動作とパニックの関係についてはRustonomiconのUnwindingの章などが参考になります。 パニックを想定した安全性 Rustではたとえパニック状態でも未定義動作だけは絶対に避ける必要があります。そのため以下の関数は不健全 (unsound)です。 use std::ptr; // この関数はRustではunsound (

    Rustのパニック機構 - 簡潔なQ
  • 安定化間近!Rustのimpl Traitを今こそ理解する - 簡潔なQ

    概要: impl Trait が安定化間近である。これはトレイトオブジェクトと似た用途を持つが、静的ディスパッチされSizedのまま使えるため効率的である。 impl Trait が安定化間近 Rustでは新規の機能はまずnightlyバージョンに「不安定機能 (unstable feature)」として取り入れられます。そこでの実験を経て、プログラミング言語Rustに半恒久的に導入してもよいと合意されたものだけが「安定化 (stabilize)」され、betaやstableバージョンのコンパイラでも使用できるようになります。 さて、現在 「impl Trait」と呼ばれる機能の安定化のめどがたったというアナウンスがありました。この機能は2016年夏ごろに実装され、長い間待ち望まれてきた目玉機能のひとつでしたが、ここにきてようやっと、という感じです。そこで、 impl Trait について

    安定化間近!Rustのimpl Traitを今こそ理解する - 簡潔なQ
  • Rustにおける演算子の型推論の特殊ルール - 簡潔なQ

    概要: 原則として x + y は ::std::ops::Add(x, y) の構文糖衣であるが、型推論で特別扱いされる。 演算子の脱糖 演算子の脱糖は型推論の後、HIRからMIRへの変換のタイミングで行われる。原則として x + y は ::std::ops::Add(x, y) の構文糖衣である。これは *x/x[i] 以外の他の演算子についても同様である。しかし型推論では以下のような特殊扱いがある。 fn main() { use std::ops::Add; let x : i8 = 1 + 1; // OK let x : i8 = Add::add(1, 1); // Error } 下側のコードがエラーになる理由 Rustの演算子はオーバーロード可能であり、型の制約が少ない。具体的には「左辺と右辺の型から、計算結果の型が一意に決まる」ということだけが要請される。そのため型

    Rustにおける演算子の型推論の特殊ルール - 簡潔なQ
    clavier
    clavier 2017/06/27
  • Rustの配置構文とbox構文 - 簡潔なQ

    概要: Rustの不安定機能である配置構文とbox構文の仕組みを説明する。 配置構文の動機 Rustの値渡しはデフォルトでムーブであり、コピーコンストラクターのような重い処理が勝手に実行されることはないから、多くの場面では値渡しのコストはそれほど高くない。それでも、大きな構造体を受け渡すと memmove のコストが高くつく場合がある。 とりわけ、データ構造に値を追加する場面では、無駄なムーブが発生している可能性が高い。これを最適化するために、ライブラリのインターフェースに工夫を加えるのが、Rustの配置構文である。C++emplace_back と似ていると考えてよいだろう。 配置構文の使い方 配置構文の具体的な構文は、以下の2種類が提案されており、今のところは確定していない。 in PLACE { EXPR } 構文 PLACE <- EXPR 構文 PLACE の部分は、配置構文

    Rustの配置構文とbox構文 - 簡潔なQ
  • Rustの型推論の概略 - 簡潔なQ

    概要: Rustの型推論の大枠を説明する。 なお、筆者もRustの型推論の動作を詳細に把握しているわけではない。 短くまとめると Rustの型推論はHindley-Milner型推論ベースである。したがって後方の式や文の内容から手前の型が推論されることもある。しかし以下に挙げるようなRust独自の特徴をもつ。 型推論は原則として関数定義の中で閉じており、関数の引数型や戻り値型は推論されない。これは、関数を抽象化の境界とするための意図的なものである。この意味で「局所的」というのであれば間違いではない。 ただし、let多相を含む型推論を避ける意図もあるかもしれない。 関数呼び出しや一部の演算子などは、その部分の制約を立てる段階で、型の一部分が判明している必要がある。この動作は推論順序の影響を受ける。 トレイトによりオーバーロード可能になっている関数や演算子は、射影型を使っている場合、ボトムアッ

    Rustの型推論の概略 - 簡潔なQ
  • RustのSizedとfatポインタ - 簡潔なQ

    概要: RustにはSizedというトレイトがあり、一部の例外を除いて暗黙のうちに実装されている。Sizedが実装されていない型はDynamically Sized Typeと呼ばれ、これらのデータはfatポインタを経由してアクセスする。この仕組みを説明する。 Sizedの使い方はAPIリファレンス、The Bookの該当部分とその日語訳、Rustonomiconの該当部分をまず読むとよい。 この記事では、コンパイラがSizedをどう実装しているかという観点からまとめ直してみた。 Sizedとは何か Sizedは標準ライブラリで定義されているトレイトである。 pub trait Sized {} Sizedトレイトは次の2つの意味をもつようだ。 Sizedを実装する型は、全て同じバイト数である。C言語のsizeofに相当するstd::mem::size_of が使える。(Sizedでない

    RustのSizedとfatポインタ - 簡潔なQ
  • combine: マクロのいらないRustのパーサーコンビネーター - 簡潔なQ

    はじめに Rustには有名なnomというパーサーコンビネーターライブラリがあるが、せっかく高級な型システムと最適化があるのにマクロで何とかしようとするのは勿体無いと思うので、マクロに深く依存しないcombineを使ってみた。 combineの主な特徴 parsec リスペクトのパーサーコンビネーター コンビネーターはマクロではなく、 Parser traitを実装する値で表す バイトストリーム、文字(Unicodeコードポイント)ストリーム、トークンストリームの全てに対応 メモリ上の文字列だけではなく、入力ストリームからの直接のパースにも対応 まだ計測はしていないが、 Box を多用していたりはしないので、速度的に大きく遅れをとるようなことはないのではないかと思う。 以下、parsecについて知っていたほうが読みやすい構成になっているので、必要ならparsecの資料を探して読むといいかもし

    combine: マクロのいらないRustのパーサーコンビネーター - 簡潔なQ
    clavier
    clavier 2017/02/20
  • C言語で部分適用したい!(実は、できるアーキテクチャがあるんです) - 簡潔なQ

    通常、C言語の関数ポインタは、クロージャではない。したがって、関数を部分適用したり、カリー化したり、ローカル変数をキャプチャーした関数ポインタを返したりすることはできない。しかし、実際にC言語が動作する環境のなかには、そのようなことが実現できるものがある。PowerPC64 System V ABIは、そのひとつである。 PowerPC64 System V ABIは、Linux等において高級言語のコードをPowerPC64機械語に翻訳するさいの取り決めである。 多くのABIでは、関数ポインタは関数の最初の命令のアドレスに翻訳されるが、PowerPC64 System V ABIはそれとは異なる定義をしている。具体的には、関数ポインタは以下のような構造体 struct Funptr { void *jump_target; /* ジャンプ先 */ void *initial_r2; /*

    C言語で部分適用したい!(実は、できるアーキテクチャがあるんです) - 簡潔なQ
  • Cプリプロセッサメタプログラミングで、文字列系泥沼関数型プログラミング - 簡潔なQ

    今年の文化祭で書いた記事です。 - C言語といえば、いやなイメージ、過去の遺産といった感じがあるかもしれません。 C言語のネガティブな側面というと、やはりポインタやメモリ管理などが難しい、ということが思いつくかもしれません。 しかし、C言語のポインタは表記に騙されやすいだけで、仕組み自体は全く難しくありません。 文法も、どこぞのPerlC++と比べたら屁でもない単純さです。 実のところ、仕様が煩雑で難しいのは、Cプリプロセッサなのであります。 普段からあまり複雑な使いかたをしないから気づかないかもしれませんが、Cプリプロセッサの置換処理は、欺瞞と裏切りに満ちた世界なのです。 これが進化するとテンプレートなどといったもっと面白いものになるのですが、今回はCプリプロセッサで計算をしちゃったりするところまで試しにやってみましょう。 (なお、GCCにより実験的に調べた記事なので、他のCコンパイラ

    Cプリプロセッサメタプログラミングで、文字列系泥沼関数型プログラミング - 簡潔なQ
  • 1