LoginSignup
1

More than 3 years have passed since last update.

Rust勉強中 - その7 -> bool型とchar型

Last updated at Posted at 2019-09-29

自己紹介

出田 守と申します。
しがない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と評価されません。下記のように試してみましたが、コンパイル時にエラーが出ました。

main.rs
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

例によって使ったソースコードを以下に載せておきます。

main.rs
...
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

今回はここまで~

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1