自己紹介
出田 守と申します。
しがないPythonプログラマです。
情報セキュリティに興味があり現在勉強中です。CTFやバグバウンティなどで腕を磨いています。主に低レイヤの技術が好きで、そっちばかり目が行きがちです。
Rustを勉強していくうえで、読んで学び、手を動かし、記録し、楽しく学んでいけたらと思います。
環境
新しい言語を学ぶということで、普段使わないWindowsとVimという新しい開発環境で行っています。
OS: Windows10 Home 64bit 1903
CPU: Intel Core i5-3470 @ 3.20GHz
Rust: 1.38.0
RAM: 8.00GB
Editor: Vim 8.1.1
Terminal: PowerShell
前回
前回は浮動小数点数について学びました。
Rust勉強中 - その6
型
bool(ブール)型
Rustのbool型はtrueとfalseを持ちます。比較演算の結果をboolとして生成します。
型 |
---|
true |
false |
Rustでは条件式を必要とする文(if文やwhile文など)ではbool値のみ評価されます。つまり、空文字や0を直接if文に書いてもfalseと評価されません。下記のように試してみましたが、コンパイル時にエラーが出ました。
fn main() {
if 0 {
println!("true");
} else {
println!("false");
}
}
$ cargo run
Compiling types v0.1.0 (C:\Users\deta\hack\rust\types)
error[E0308]: mismatched types
--> src\main.rs:142:8
|
142 | if 0 {
| ^ expected bool, found integer
|
= note: expected type `bool`
found type `{integer}`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: Could not compile `types`.
To learn more, run the command again with --verbose.
bool型のキャスト
bool型から整数型へキャストができるようです。
式 | 結果 |
---|---|
true as u32 | 1u32 |
false as u32 | 0u32 |
true as i32 | 1i32 |
false as i32 | 0i32 |
ただし、整数型からbool型へキャストはできません。以下のようにエラーを吐きます。
$ cargo run
Compiling types v0.1.0 (C:\Users\deta\hack\rust\types)
error[E0054]: cannot cast as `bool`
--> src\main.rs:147:37
|
147 | println!("1 as bool = {}{}", 1 as bool, get_type(1 as bool));
| ^^^^^^^^^ help: compare with zero instead: `1 != 0`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0054`.
error: Could not compile `types`.
char(文字)型
char型は32bit(4byte)でUnicodeの一文字を表します。
文字リテラル
char型はシングルクオート(')で文字を囲みます。U+0000~U+007Fの間であれば'\xhh'で書くことができます(hは16進数)。さらに'\u{hhhhhh}としても書くことができます。
文字リテラル | 補足 |
---|---|
'a' | char型のa |
'\x61' | char型のa |
'\u{61}' | char型のa |
''' | char型の' |
'\' | char型の| |
'\n' | char型のLine feed |
'\r' | char型のCarriage return |
'\t' | char型の水平タブ |
char型のキャスト
char型から整数型へのキャストができます。変換先の型に収まらない場合はその型のサイズに丸められます。
また、u8型からchar型へのキャストができます。
式 | 結果 |
---|---|
'a' as i32 = 97i32(0x61) | |
'\u{100}' as i8 | 0i8(0b00000000) |
0x61u8 as char | a |
char型のメソッド
メソッド例を以下に紹介します。一部のメソッドはOption型を返します。
式 | 結果 |
---|---|
'f'.is_digit(16) | true |
'f'.is_numeric() | true |
'f'.to_digit(16) | Some(15) |
'0xf'.to_digit(16) | Some(15) |
'f'.to_digit(10) | None |
std::char::from_u32(0x61) | Some('a') |
std::char::from_u32(0x7f) | Some('\u{7f}') |
std::char::from_u32(0x110000) | None |
例によって使ったソースコードを以下に載せておきます。
...
fn print_bool() {
println!("\n[print bool examples]");
println!("true: \tvalue={}, \ttype={}", true, get_type(true));
println!("!true: \tvalue={}, \ttype={}", !true, get_type(!true));
println!("false: \tvalue={}, \ttype={}", false, get_type(false));
println!("!false: \tvalue={}, \ttype={}", !false, get_type(!false));
println!("0==0: \tvalue={}, \ttype={}", 0==0, get_type(0==0));
println!("0!=0: \tvalue={}, \ttype={}", 0!=0, get_type(0!=0));
println!("0==0&&0==0: \tvalue={}, \ttype={}", 0==0&&0==0, get_type(0==0&&0==0));
println!("0!=0&&0==0: \tvalue={}, \ttype={}", 0!=0&&0==0, get_type(0!=0&&0==0));
println!("0!=0||0==0: \tvalue={}, \ttype={}", 0!=0||0==0, get_type(0!=0||0==0));
}
fn print_bool_cast() {
println!("\n[print bool cast]");
println!("true as u32 = {}{}", true as u32, get_type(true as u32));
println!("false as u32 = {}{}", false as u32, get_type(false as u32));
println!("true as i32 = {}{}", true as i32, get_type(true as i32));
println!("false as i32 = {}{}", false as i32, get_type(false as i32));
// println!("1 as bool = {}{}", 1 as bool, get_type(1 as bool));
// println!("0 as bool = {}{}", 0 as bool, get_type(0 as bool));
}
fn print_char_literals() {
println!("\n[print char literals]");
println!("'a': \ttype={}, \tvalue={}", get_type('a'), 'a');
println!("'\\x61': \ttype={}, \tvalue={}", get_type('\x61'), '\x61');
println!("'\\u{}61{}': \ttype={}, \tvalue={}", '{', '}', get_type('\u{61}'), '\u{61}');
println!("'\\'': \ttype={}, \tvalue={}", get_type('\''), '\'');
println!("'\\\\': \ttype={}, \tvalue={}", get_type('\\'), '\\');
println!("'\\n': \ttype={}, \tvalue={}", get_type('\n'), '\n');
println!("'\\r': \ttype={}, \tvalue={}", get_type('\r'), '\r');
println!("'\\t': \ttype={}, \tvalue={}", get_type('\t'), '\t');
}
fn print_char_cast() {
println!("\n[print char cast]");
println!("'a' as i32 = {}{}(0x{:x})", 'a' as i32, get_type('a' as i32), 'a' as i32);
println!("'\\u{}100(0b{:08b}){}' as i8 = {}{}(0b{:08b})", '{', 0x100, '}', '\u{100}' as i8, get_type('\u{100}' as i8), '\u{100}' as i8);
println!("0x61u8 as char = {}", 0x61u8 as char);
// println!("0x61i32 as char = {}", 0x6132 as char);
}
fn print_char_methods() {
println!("\n[print char methods]");
println!("'f'.is_digit(16) = {}", '1'.is_digit(16));
println!("'f'.is_numeric() = {}", '1'.is_numeric());
println!("'f'.to_digit(16) = {:?}", 'f'.to_digit(16));
println!("'0xf'.to_digit(16) = {:?}", 'f'.to_digit(16));
println!("'f'.to_digit(10) = {:?}", 'f'.to_digit(10));
println!("std::char::from_u32(0x61) = {:?}", std::char::from_u32(0x61));
println!("std::char::from_u32(0x7f) = {:?}", std::char::from_u32(0x7f));
println!("std::char::from_u32(0x110000) = {:?}", std::char::from_u32(0x110000));
}
fn main() {
// println!(">> Integer type <<");
// print_int_range();
// print_int_literals();
// print_byte_literals();
// print_int_cast();
// print_int_methods();
// println!(">> Floating point type <<");
// print_float_range();
// print_float_literals();
// print_float_cast();
// print_float_methods();
println!(">> Bool type <<");
print_bool();
print_bool_cast();
println!(">> Char type <<");
print_char_literals();
print_char_cast();
print_char_methods();
}
$ cargo run
Compiling types v0.1.0 (C:\Users\deta\hack\rust\types)
Finished dev [unoptimized + debuginfo] target(s) in 0.62s
Running `target\debug\types.exe`
>> Bool type <<
[print bool examples]
true: value=true, type=bool
!true: value=false, type=bool
false: value=false, type=bool
!false: value=true, type=bool
0==0: value=true, type=bool
0!=0: value=false, type=bool
0==0&&0==0: value=true, type=bool
0!=0&&0==0: value=false, type=bool
0!=0||0==0: value=true, type=bool
[print bool cast]
true as u32 = 1u32
false as u32 = 0u32
true as i32 = 1i32
false as i32 = 0i32
>> Char type <<
[print char literals]
'a': type=char, value=a
'\x61': type=char, value=a
'\u{61}': type=char, value=a
'\'': type=char, value='
'\\': type=char, value=\
'\n': type=char, value=
'\r': type=char, value=
'\t': type=char, value=
[print char cast]
'a' as i32 = 97i32(0x61)
'\u{100(0b100000000)}' as i8 = 0i8(0b00000000)
0x61u8 as char = a
[print char methods]
'f'.is_digit(16) = true
'f'.is_numeric() = true
'f'.to_digit(16) = Some(15)
'0xf'.to_digit(16) = Some(15)
'f'.to_digit(10) = None
std::char::from_u32(0x61) = Some('a')
std::char::from_u32(0x7f) = Some('\u{7f}')
std::char::from_u32(0x110000) = None
今回はここまで~