Rustなにもわからない
なあなあでやっている感じのところがあるのでわかるようになりたい
- 属性
- マクロ
コンパイラの言われたとおりに修正すればいいRustは非常に良い言語だけど何もわからない
あとクレート使ったときに補完がでないやつがあるので何もわからない(けどしっかりコンパイラに怒られるので謎)
リリースビルドで環境変数を渡したい
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なのかはわからない…
環境変数が変わった時、パス内のファイルが変わったときなどに適切にビルドするためには上のようなものを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〜がそもそもおまじないという認識でしかないのでどうにかわかるようになりたい
道は険しい
`a みたいなやつが理解できない。う〜ん
Rustのマクロの利点ってなんなんだろう
"1234"みたいなやつを分解してVec<char>にする
fn str_to_char_vec(str: String) -> Vec<char> {
str.chars().collect()
}
charを数字にする
"0".to_digit(10).unwrap()
to_digit
では Option
が返ってくるので実際には unwrap
はしない
*
とclone
の使い分けがわからない
cloneはコピーで*は参照から値を取るというイメージなんだけど
RefCell
、Box
などのイメージがまだあんまりついていない。
LinkedListやフォルダ構造のようなネスト階層にしたものを参照で直接いじる場合、おこられが発生しやすくなる。
こういったものの場合最初に加工してからつなげたほうがいいのだろうか。何もわからない
clone
でよしなにできる感があるけど、オブジェクト全体を clone
するのかそのプロパティを clone
するのかで色々変わってくる気がする。そもそも所有権周りが全然駄目な気がする
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を使う
書きかけ
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,
}
);
Option
はNone
、文字は""
、数字は0
になる。
Defaultは上書きすることも可能。すごい便利。
Rust
で三項演算子みたいなやりかた
let text = if is_xxx {
"aaa".to_string()
} else {
"bbb".to_string()
}
bool
でなにか分けたいときは上のように書ける。三項演算子みたいに1行とはいかないけど、中にロジックを入れたくなる場合もあるのでその場合は非常に使いやすい
ライフタイムがまだわかってない…
自動生成で'static
が定義されているものに'a
を突っ込むと死ぬ。逆もしかり。ハマると抜け出せない