Open8

rustの初歩的な質問

sadnessOjisansadnessOjisan

配列のindexとして何かしらの変数を使うとき、as usizeは仕方ないことなのか?asは気軽に使っていいもの?

https://github.com/sadnessOjisan/calendarize/blob/main/src/lib.rs#L28

magurotunamagurotuna

https://doc.rust-lang.org/nomicon/casts.html

キャストについてはここによくまとめられています。
とりあえず数値型のキャストに注目すると、情報量の多い型(例: u32)から少ない型(例: u8)へのキャストは truncate が発生する、f32 や f64 が絡むとややこしい規則がある、などがあることは頭の片隅に置いておく必要がありますが、calendarize のケースではまったく問題ないかなと思います。

ただ、calendarize のコードをざっと見た印象では、as usize せずとも最初からすべて usize で扱ってしまっても(u32 は使わない)良いのでは?という気もしました。

sadnessOjisansadnessOjisan

usize が確保するサイズって実行環境ごとに変わるからあまり使わない方が良いと思っていたのですが、そうでもないんですか?開発者が縛れる制約は厳しい方が良いと思っています。

それはそうと日付の最大数が31なのでu32 はサイズ取りすぎな気もしてきましたw

magurotunamagurotuna

usize が確保するサイズって実行環境ごとに変わるからあまり使わない方が良いと思っていたのですが、そうでもないんですか?

確かにそうかも……競プロとかの文脈では手抜きのために全部 usize でやってしまうことが多くて、大きな実害もないし良いやと思ってましたが、メモリアドレス空間の大きさに関係ないような文脈では避けたほうが望ましいかもしれません。
https://users.rust-lang.org/t/i32-vs-isize-u32-vs-usize/22657/6

そういう意味では、chrono の API は u32 を受け取るような設計になっているみたいなので、それにならって 基本は u32 を使い、インデックスアクセスしたいときに as usize する、っていう書き方(つまり今の書き方)で良さそうですね。

sadnessOjisansadnessOjisan

ライブラリの関数の引数にchronoの型を持つのは正しい?date型がないからそうしてしまった。外部クレートとはいえ準公式とのことなので良いのかなと思ってる。

https://github.com/sadnessOjisan/calendarize/blob/main/src/lib.rs#L4

magurotunamagurotuna

外部クレートの型を公開APIのインターフェースに含めるのは、それが必要なのであれば全然だいじょうぶだと思います。このような場合は、calendarize から chrono の NaiveDate を re-export する、みたいな方法がとられることも多いです。以下の記事にかかれているようなやり方です。
https://qiita.com/tasshi/items/c6548fb38f842c769d85

ただ、calendarize のケースでは、calendarize 関数の引数で year: usize, month: usize を受け取る形でも良いかも?とは感じます。

sadnessOjisansadnessOjisan

re-export いいですね!やってみます!

calendarize 関数の引数で year: usize, month: usize を受け取る形でも良いかも?とは感じます

ライブラリ側で日付変換すると、month に 13 渡されたときの異常系設計がめんどくさくてサボりましたw JS だと Date を渡せるから、Rust でも同じようにできないかなと思ってという意図もあり、日付型で受け取るようにしてみました。

sadnessOjisansadnessOjisan

ランタイムで、30 行目で落ちるのはなぜ?(comment out すると動く)

use chrono::prelude::*;
use wasm_bindgen::prelude::*;
use yew::prelude::*;

struct Model {
}


enum Msg {
}

impl Component for Model {
    type Message = Msg;
    type Properties = ();

    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self {
        }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        true
    }

    fn change(&mut self, _props: Self::Properties) -> ShouldRender {
        false
    }

    fn view(&self) -> Html {
        let local: DateTime<Local> = Local::now(); // FIXME: ランタイムでここで落ちる
        html! {
        <p>{"aaaaaaaaaaaaaa"}</p>
        }
    }
}

#[wasm_bindgen(start)]
pub fn run_app() {
    App::<Model>::new().mount_to_body();
}