メモ帳
todo:
gitも一緒にできる
cargo init
ここが始まり
fn main() {}
println!(data);
// or
print!(data);
println!("{}", data_not_str);
Rustはlet
で変数定義を行う
ただ、何も考えないと定数として扱われる
let i = 0;
i = 1; // error
let mut
とすれば変数になる
let mut i = 0;
i = 1; // ok
未指定でi32
i8
-> char
i16
-> short
i32
-> int
i64
-> long
i128
-> ?u8
-> unsigned char
u16
-> unsigned short
u32
-> unsigned int
u64
-> unsigned long
u128
-> ?未指定(0.0
等)でf64
f16
-> ?f32
-> float
f64
-> double
f128
-> ?インデックスを扱うときに使う
usize
-> unsigned int
or unsigned long
// 数値から数値
// 一番かんたんなものは
// 値または変数 as 型名
let a: i32 = -10;
let b: u64 = a as u64;
assert_eq!(b, 0); // こういうことが起きる
// float to intはこうするしかない
// 絶対安全な型変換は
// 型名::from(値);
let c: i64 = i64::from(a);
// 安全でない型変換は
// 型名::try_into(値); (返り値: Result<...>)
let d: Result<u32, std::num::TryFromIntError> = u32::try_from(a);
// 文字列(&str, String)から数値 (返り値: Result<...>)
let e = "10";
let f = a.parse();
&str
-> char *
String
-> std::string
// 何も指定しないと&'static str型となる
// 基本は&str型としておく
let a: &str = "aaa";
// Stringは以下の通り
let b: String = String::from("bbb");
let c: String = String::from(a);
// &strのコピーはCのchar *と同じくかんたんにはできない
// Stringのコピーは以下の通り
let d: String = b.clone();
// 文字列の結合は+を使うだけ
// ただし、一番最初の型はString, それ以外は&strまたは&String
let e: String = d + &c + &b + a;
// Stringでは二度以上参照すると所有権の問題でエラーが出る
let f: String = e + &e; // error
// clone()でコピーする必要がある
let g: String = e.clone() + &e.clone();
// String -> &str
let a: String = String::from("a");
let b: &str = &a;
// 数値 -> 文字列
let c: i32 = 0;
let d: String = c.to_string();
長さの変更ができない
// 配列定義
// [初期値;長さ]
let mut arr = [0;10];
// [...値]
let arr2 = [1, 2, 3, 4, 5];
可変長配列
// Vec定義
// vec![]
let mut vec1: Vec<i32> = vec![];
// vec![初期値;長さ]
let mut vec2: Vec<i32> = vec![0;10];
// vec![...要素]
let mut vec3: Vec<i32> = vec![0,1,2,3,4];
// push()で末尾に追加できる (mut必要)
vec1.push(10);
// pop()で末尾を取り出せる (mut必要)
let a: Option<i32> = vec1.pop();
// 取り出すのはいつもどおり
assert_eq!(arr[0], 0);
// Option<...>でも取り出せる(こちらのほうが安全)
let b: Option<i32> = arr.get(0);
// 長さはlen()
let size: uzise = arr.len();
// sortでソートができる (mut必要) 最悪計算量がO(n * log(n))
arr.sort();
結果と返り値を持つもの, Ok()
or Err()
is_ok()
やis_err()
で問題の有無を確認でき、ok()
やerr()
で内容をOption<...>
で取得できる
値を持たないかもしれないもの, Some()
or None
配列.get(インデックス)
で配列外を参照したときなどに出てくる
条件式では()
がいらない
if
let a: i32 = 0;
if a > 0 {
println!("a is positive");
} else if a < 0 {
println!("a is negative")
} else {
println!("a is zero")
}
ifは文ではなく式のため、以下のようなことができる
let a = 0;
// ifの結果をbに代入する
// この場合はelseが必須
let b = if a > 0 {
"positive" // ここに;がないのは、これを返り値とするため。
} else if a < 0 {
"negative"
} else {
"zero"
}; // ここに;が必要
println!("{}", b);
無限ループ
loop {
println!("!");
}
println!("?"); // ここには到達しない
条件を満たす限り繰り返す
条件式には()
不要
let mut i = 0;
while i < 10 {
i += 1;
}
assert_eq!(i, 10);
範囲内で繰り返す
let a: Vec<i32> = vec![0, 1, 2];
for x in a.iter() {
// ^^^^^^^^ forで回すには配列.iter()とする
println!("{}", x);
}
println!("{:?}", a);
for x in a {
// ^ 配列.iter()としないと
println!("{}", x);
}
println!("{:?}", a); // error: ここで利用できない
以下のようなことができる
let a: Vec<i32> = vec![0, 1, 2];
let b: Option<&i32> = a.get(3);
if let Some(c: &i32) = b {
println!("{}", c);
} else {
println!("None");
}
if_letと同じ使い方
fn
で始める
どの場所に書いても構わない(利用よりも上に宣言を書く必要がない)
fn main() {
test();
}
fn test() {
println!("hello");
}
println!
とかvec!
とかの!
で終わるやつ
let mut vec1 = vec![0;5];
// ^^^^ here
for a in vec1 {
println!("{}", a);
//^^^^^^^^ here
}
マクロ名!(変数など)
またはマクロ名![変数など]
またはマクロ名!{変数など}
でできる
違いはない
// 全部意味は同じ
let mut vec1 = vec!(0;10);
let mut vec2 = vec![0;10];
let mut vec3 = vec!{0;10};
macro_rules!
から始まる
macro_rules! test {
// 変数が何もない場合
() => {
// マクロ内でマクロを使うこともできる
println!("test");
};
// 変数を用いる場合
// !TODO
}