Open13

Rustなにもわからない

tanshiotanshio

なあなあでやっている感じのところがあるのでわかるようになりたい

  • 属性
  • マクロ

コンパイラの言われたとおりに修正すればいいRustは非常に良い言語だけど何もわからない
あとクレート使ったときに補完がでないやつがあるので何もわからない(けどしっかりコンパイラに怒られるので謎)

tanshiotanshio

リリースビルドで環境変数を渡したい

STAGING=1 cargo build --release

上のような感じにしたい

build.rsで、

    if let Ok(val) = env::var("STAGING") {
        println!("cargo:rustc-env=STAGING={}", val);
    };
    println!("cargo:rerun-if-env-changed=STAGING");

にしてあげるといい。
なぜprintInなのかはわからない…

https://doc.rust-lang.org/cargo/reference/build-scripts.html
Rustはとても賢く、ビルド時に色々キャッシュされているみたいで、上のようなことをしないといくら環境変数を変えたところで挙動が変わらない。
環境変数が変わった時、パス内のファイルが変わったときなどに適切にビルドするためには上のようなものをbuild.rsに書かなくてはならない。

#[cfg(debug_assertions)] と一緒に使ってやるといい感じになる

#[cfg(not(debug_assertions))]
fn get_api() -> String {
    let staging = env!("STAGING");
    if staging == "1" {
        "ステージング".to_owned()
    } else {
        "本番".to_owned()
    }
}

#[cfg(debug_assertions)]
fn get_api() -> String {
    "開発用".to_owned()
}

#[cfg〜がそもそもおまじないという認識でしかないのでどうにかわかるようになりたい
道は険しい

tanshiotanshio

"1234"みたいなやつを分解してVec<char>にする

fn str_to_char_vec(str: String) -> Vec<char> {
    str.chars().collect()
}
tanshiotanshio

charを数字にする

"0".to_digit(10).unwrap()

to_digit では Option が返ってくるので実際には unwrap はしない

tanshiotanshio

*cloneの使い分けがわからない
cloneはコピーで*は参照から値を取るというイメージなんだけど

tanshiotanshio

RefCellBoxなどのイメージがまだあんまりついていない。
LinkedListやフォルダ構造のようなネスト階層にしたものを参照で直接いじる場合、おこられが発生しやすくなる。
こういったものの場合最初に加工してからつなげたほうがいいのだろうか。何もわからない

tanshiotanshio

clone でよしなにできる感があるけど、オブジェクト全体を clone するのかそのプロパティを clone するのかで色々変わってくる気がする。そもそも所有権周りが全然駄目な気がする

tanshiotanshio

HashMap

Rust のハッシュマップの作成方法は以下

作成方法

let mut hash_map = HashMap::new();

追加

insert を使う

hash.insert("aaa", "aaa");

削除

remove を使う

hash.remove("aaa");

削除では、存在しないキーを入れたところでエラーにはならない
remove の返り値は Option<T>

存在するかのチェック

contains_key を使う

let has_ddd = hash.contains_key("ddd");

実際にはあったら、なかったらで処理をするはず。後述する Entry API を使うと便利。

取得

getを使う

あったら何かする系

match hash.get("aaa") {
  Some(value) => {
    // ある場合の処理
  }
  None => {
    // ない場合の処理
  }
}

get_key_value
キーと値を取りたいときに使う

Entryを使う

書きかけ

tanshiotanshio

Defaultが便利

structを定義して、属性にDefaultを追加、するとdefault が使える

#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct Item {
    name: String,
    option: Option<String>,
}

#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct ItemNumber {
    number: usize,
    option: Option<String>,
}

テスト

    #[test]
    fn test_default() {
        let item = Item::default();
        assert_eq!(
            item,
            Item {
                name: "".to_string(),
                option: None
            }
        );

        let num = ItemNumber::default();
        assert_eq!(
            num,
            ItemNumber {
                number: 0,
                option: None,
            }
        );

OptionNone、文字は""、数字は0になる。
Defaultは上書きすることも可能。すごい便利。

tanshiotanshio

Rustで三項演算子みたいなやりかた

let text = if is_xxx {
  "aaa".to_string()
} else {
  "bbb".to_string()
}

bool でなにか分けたいときは上のように書ける。三項演算子みたいに1行とはいかないけど、中にロジックを入れたくなる場合もあるのでその場合は非常に使いやすい

tanshiotanshio

ライフタイムがまだわかってない…
自動生成で'static が定義されているものに'aを突っ込むと死ぬ。逆もしかり。ハマると抜け出せない