タグ

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

  • Rustでグラフを表現するにはTyped Arenaが便利 - 簡潔なQ

    概要: Rustでグラフのように相互参照を含むデータ構造を表現するには、Typed Arenaという方法が適している。これについて説明する 整数による表現 グラフの表現方法で、最も簡単なのは、ノードを整数で表し、グラフのデータを別に持つ方法である。 fn main() { let mut edges = vec![vec![]]; edges[0].push(0); edges.push(vec![]); edges[1].push(0); } これは大抵どんな言語でも同じように使えるし、場合によってはこちらで済ませてしまったほうが簡単かもしれない。特に競技プログラミングではノードに付与されている情報が少なかったり、ノードに明示的に整数が付番されていたりするため、ほとんどの場合整数で表現するほうが扱いやすい。 しかしこの方法では、整数とグラフデータとの対応関係を見失いやすいと考えられる。整

    Rustでグラフを表現するにはTyped Arenaが便利 - 簡潔なQ
    udzura
    udzura 2024/01/14
  • PhantomDataまとめ - 簡潔なQ

    概要: PhantomData<T> には3つの異なる役割があり、多くの場合は PhantomData<fn() -> T> の形で使うのが無難である。 はじめに PhantomData<T>は特殊な型で、中身を持たないにもかかわらず、型システム上は中身を持つかのように振る舞います。幽霊型 (phantom type) と関係はありますが、幽霊型そのものではないので注意が必要です。 PhantomData の基的な使い方 幽霊型を使う場合や、何らかの理由で構造体の外部にある型を指定する必要がある場合を考えます。例えば、幽霊型で単位を区別する // U は Meter や Miles のような型が入るとする struct UnitFloat<U: Unit> { inner: f64, } や、外部にあるデータを参照する struct ExtVec<T> { // 中身はなし } のような

    PhantomDataまとめ - 簡潔なQ
    udzura
    udzura 2022/05/12
  • Rustの日付時刻処理(std::time, time, chrono) - 簡潔なQ

    標準ライブラリ 標準ライブラリには時刻を扱うための基礎となる型のみが定義されている。暦やタイムゾーンなどを扱うときは後述の chrono を使うのがよい。 std::time::Duration ... 時間。 std::time::Instant ... 体内時計の時刻。 std::time::SystemTime ... 時計の時刻。 Duration 時間はOSとは無関係なのでlibcoreに定義されている。 src/libcore/time.rs pub struct Duration { secs: u64, nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC } したがってこれは0秒以上264秒未満の範囲内の時間をナノ秒単位で正確に表現できる。 InstantとSystemTime 標準ライブラリには時刻を表す型が Instant

    Rustの日付時刻処理(std::time, time, chrono) - 簡潔なQ
    udzura
    udzura 2021/05/26
    コアにはmonotonicとrealtimeの違いそのものの2つの構造体がある
  • RustでOptionやResultの配列ができてしまったときの一般的なテク4つ - 簡潔なQ

    Vec<Result<_>> ではなく Result<Vec<_>> を得る collect() 関数を使うと、 Vec<Result<_>> を得ることもできるし、 Result<Vec<_>> を得ることもできる。変換先の型を明示することで区別する。 fn main() { // 全てSomeならSome(配列)を返し、どれかがNoneなら全体もNoneになる assert_eq!([Some(1), Some(2)].iter().cloned().collect::<Option<Vec<_>>>(), Some(vec![1, 2])); assert_eq!([None, Some(2)].iter().cloned().collect::<Option<Vec<_>>>(), None); } これができるのは以下の理由による。 FromIterator は多対多である。つま

    RustでOptionやResultの配列ができてしまったときの一般的なテク4つ - 簡潔なQ
    udzura
    udzura 2021/05/06
  • combine: マクロのいらないRustのパーサーコンビネーター - 簡潔なQ

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

    combine: マクロのいらないRustのパーサーコンビネーター - 簡潔なQ
    udzura
    udzura 2021/04/29
  • Rustの身代わりパターン - 簡潔なQ

    概要: &mut 参照に対して所有権が必要な操作をするときは特定のパターンが用いられる。これを身代わりパターンとでも呼ぶことにする。 例: 単方向リンクリスト またしても単方向リンクリストを考える。 struct List<T> { root: Option<Box<Node<T>>>, } struct Node<T> { value: T, next: Option<Box<Node<T>>>, } これに対する push_front を実装してみる。ナイーブに書くと以下のような感じになる。 impl<T> List<T> { fn push_front(&mut self, value: T) { self.root = Some(Box::new(Node { value: value, next: self.root, })); } } ところがこれはエラーになる。 error[

    Rustの身代わりパターン - 簡潔なQ
    udzura
    udzura 2021/03/16
  • 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
    udzura
    udzura 2021/02/16
  • Rustのderiveはあまり頭がよくない - 簡潔なQ

    概要: Rustの derive はあまり頭がよくない。 derive がドジを踏む例 derive の問題は顕在化しやすく、RustコンパイラのGitHub上でも何度も重複するissueが投げられていた。今は主に #26925 を中心に議論がまとまっているので、そちらを参照するとよいだろう。 不必要な境界を与える例 use std::rc::Rc; // 来不必要な X: Clone を要求する #[derive(Clone)] struct A<X>(Rc<X>); struct B; fn main() { A(Rc::new(B)).clone(); // Error } error: no method named `clone` found for type `A<B>` in the current scope --> <anon>:10:19 | 10 | A(Rc::n

    Rustのderiveはあまり頭がよくない - 簡潔なQ
    udzura
    udzura 2021/01/15
  • 1