1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rust勉強中 - その10 -> 文字列型

Last updated at Posted at 2019-10-02

自己紹介

出田 守と申します。
しがない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勉強中 - その9

文字列型

Rustの文字列型には2つあります。

  1. ある文字列の位置を指す&str
  2. ヒープメモリ上に確保される文字列を指すString

バイト文字列

バイト文字列は、u8の列からなるスライスです。先頭にbを付けることで生成できます。

fn print_byte_string() {
    println!("\n[print byte string]");
    println!("b\"\\\"byte string\\\"\" = {:?} {:?}", b"\"byte string\"", get_type(b"byte string"));
}
[print byte string]
b"\"byte string\"" = [34, 98, 121, 116, 101, 32, 115, 116, 114, 105, 110, 103, 34] "&[u8; 11]"

raw string

以前にも説明しましたraw stringです。一部の文字をエスケープをせずにそのまま出力することができます。

fn print_raw_string() {
    println!("\n[print raw string]");
    println!("r#\"\"raw string\"\"# = {} {}", r#""raw \nstring""#, get_type(r#"raw \nstring"#));
}
[print raw string]
r#""raw string""# = "raw \nstring" &str

&str型の生成

&str(「string slice」)は連続したUTF-8テキストへの参照を借用しています。&strは常に有効なUTF-8を指します。また、&strもほかのスライスのように、fat pointerです。つまり、文字列のある位置を指したポインタと要素数を持っています。

fn print_string_slice() {
    println!("\n[print string slice]");
    println!("{} {}", "\"string slice\"", get_type("string slice"));
}
[print string slice]
"string slice" &str

&strの文字へのアクセス

こちらもほかのスライスと同じようなアクセスができます。

fn print_string_slice_access() {
    println!("\n[print string slice access]");
    println!("&\"string slice\"[..6] = {} {}", &"string slice"[..6], get_type("string slice"));
    println!("&\"ストリング スライス\"[..6] = {} {}", &"ストリング スライス"[..6], get_type("ストリング スライス"));
    println!("&\"ストリング スライス\"[..15] = {} {}", &"ストリング スライス"[..15], get_type("ストリング スライス"));
}
[print string slice access]
&"string slice"[..6] = string &str
&"ストリング スライス"[..6] = スト &str
&"ストリング スライス"[..15] = ストリング &str

ASCIIは1byteで、UTF-8は複数byteで格納しています。なので上記のような結果になっています。注意が必要です。

&strのメソッド

一部のメソッドを載せておきます。

fn print_string_slice_methods() {
    println!("\n[print string slice methods]");
    println!("\"string slice\".len() = {}", "string slice".len());
    println!("\"ストリング スライス\".len() = {}", "ストリング スライス".len());
    println!("\"ストリング スライス\".chars() = {:?}", "ストリング スライス".chars());
    println!("\"ストリング スライス\".chars().count() = {}", "ストリング スライス".chars().count());
    println!("\"string slice\".contains(\"sli\") = {}", "string slice".contains("sli"));
    println!("\"string slice\".to_uppercase() = {}", "string slice".to_uppercase());
    println!("\"String Slice\".to_lowercase() = {}", "String Slice".to_lowercase());
    println!("\"\\nstring \\tslice\\n\".trim() = {}", "\nstring slice\n".trim());
}
[print string slice methods]
"string slice".len() = 12
"ストリング スライス".len() = 30
"ストリング スライス".chars() = Chars(['ス', 'ト', 'リ', 'ン', 'グ', '\u{3000}', 'ス', 'ラ', 'イ', 'ス'])
"ストリング スライス".chars().count() = 10
"string slice".contains("sli") = true
"string slice".to_uppercase() = STRING SLICE
"String Slice".to_lowercase() = string slice
"\nstring \tslice\n".trim() = string slice

Stringの生成方法

&strをスライスへの参照とするなら、Stringはベクタといった位置づけです。
Stringの生成方法は様々にあるようです。

  1. String::newとString::with_capacityから生成
  2. to_stringメソッドから生成
  3. format!マクロから生成
  4. concatメソッド, joinメソッドから生成

などなど色々あるようです。

fn print_String() {
    println!("\n[print String]");
    println!("String::new()             = {} {}", String::new(), get_type(String::new()));
    println!("String::with_capacity(6)  = {} {}", String::with_capacity(6), get_type(String::with_capacity(6)));
    println!("\"String\".to_string()    = {} {}", "String".to_string(), get_type("String".to_string()));
    println!("format!(\"{}\", \"String\") = {} {}", "{}", format!("{}", "String"), get_type(format!("{}", "String")));
    println!("[\"Str\", \"ing\"].concat() = {} {}", ["Str", "ing"].concat(), get_type(["Str", "ing"].concat()));
}

[print String]
String::new()             =  alloc::string::String
String::with_capacity(6)  =  alloc::string::String
"String".to_string()    = String alloc::string::String
format!("{}", "String") = String alloc::string::String
["Str", "ing"].concat() = String alloc::string::String

Stringのメソッド

一部メソッドを載せておきます。

fn print_String_methods() {
    println!("\n[print String methods]");
    let mut s = String::new();
    println!("s.push('S'); s.push_str(\"tring\") = {}", {s.push('S'); s.push_str("tring"); s});
    println!("\"String\".to_string().len() = {}", "String".to_string().len());
    println!("\"String\".to_string().capacity() = {}", "String".to_string().capacity());
    println!("\"String\".to_string().remove(0) = {}", "String".to_string().remove(0));
}
[print String methods]
s.push('S'); s.push_str("tring") = String
"String".to_string().len() = 6
"String".to_string().capacity() = 6
"String".to_string().remove(0) = S

使用したソース

...
fn print_byte_string() {
    println!("\n[print byte string]");
    println!("b\"\\\"byte string\\\"\" = {:?} {:?}", b"\"byte string\"", get_type(b"byte string"));
}

fn print_raw_string() {
    println!("\n[print raw string]");
    println!("r#\"\"raw string\"\"# = {} {}", r#""raw \nstring""#, get_type(r#"raw \nstring"#));
}

fn print_string_slice() {
    println!("\n[print string slice]");
    println!("{} {}", "string slice", get_type("string slice"));
}

fn print_string_slice_access() {
    println!("\n[print string slice access]");
    println!("&\"string slice\"[..6] = {} {}", &"string slice"[..6], get_type(&"string slice"[..6]));
    println!("&\"ストリング スライス\"[..6] = {} {}", &"ストリング スライス"[..6], get_type(&"ストリング スライス"[..6]));
    println!("&\"ストリング スライス\"[..15] = {} {}", &"ストリング スライス"[..15], get_type(&"ストリング スライス"[..15]));
}

fn print_string_slice_methods() {
    println!("\n[print string slice methods]");
    println!("\"string slice\".len() = {}", "string slice".len());
    println!("\"ストリング スライス\".len() = {}", "ストリング スライス".len());
    println!("\"ストリング スライス\".chars() = {:?}", "ストリング スライス".chars());
    println!("\"ストリング スライス\".chars().count() = {}", "ストリング スライス".chars().count());
    println!("\"string slice\".contains(\"sli\") = {}", "string slice".contains("sli"));
    println!("\"string slice\".to_uppercase() = {}", "string slice".to_uppercase());
    println!("\"String Slice\".to_lowercase() = {}", "String Slice".to_lowercase());
    println!("\"\\nstring \\tslice\\n\".trim() = {}", "\nstring slice\n".trim());
}

fn print_String() {
    println!("\n[print String]");
    println!("String::new()             = {} {}", String::new(), get_type(String::new()));
    println!("String::with_capacity(6)  = {} {}", String::with_capacity(6), get_type(String::with_capacity(6)));
    println!("\"String\".to_string()    = {} {}", "String".to_string(), get_type("String".to_string()));
    println!("format!(\"{}\", \"String\") = {} {}", "{}", format!("{}", "String"), get_type(format!("{}", "String")));
    println!("[\"Str\", \"ing\"].concat() = {} {}", ["Str", "ing"].concat(), get_type(["Str", "ing"].concat()));
}

fn print_String_methods() {
    println!("\n[print String methods]");
    let mut s = String::new();
    println!("s.push('S'); s.push_str(\"tring\") = {}", {s.push('S'); s.push_str("tring"); s});
    println!("\"String\".to_string().len() = {}", "String".to_string().len());
    println!("\"String\".to_string().capacity() = {}", "String".to_string().capacity());
    println!("\"String\".to_string().remove(0) = {}", "String".to_string().remove(0));
}

fn main() {
    ...
    println!("\n>> String type <<");
    print_byte_string();
    print_raw_string();
    print_string_slice();
    print_string_slice_access();
    print_string_slice_methods();
    print_String();
    print_String_methods();
}
>> String type <<

[print byte string]
b"\"byte string\"" = [34, 98, 121, 116, 101, 32, 115, 116, 114, 105, 110, 103, 34] "&[u8; 11]"

[print raw string]
r#""raw string""# = "raw \nstring" &str

[print string slice]
string slice &str

[print string slice access]
&"string slice"[..6] = string &str
&"ストリング スライス"[..6] = スト &str
&"ストリング スライス"[..15] = ストリング &str

[print string slice methods]
"string slice".len() = 12
"ストリング スライス".len() = 30
"ストリング スライス".chars() = Chars(['ス', 'ト', 'リ', 'ン', 'グ', '\u{3000}', 'ス', 'ラ', 'イ', 'ス'])
"ストリング スライス".chars().count() = 10
"string slice".contains("sli") = true
"string slice".to_uppercase() = STRING SLICE
"String Slice".to_lowercase() = string slice
"\nstring \tslice\n".trim() = string slice

[print String]
String::new()             =  alloc::string::String
String::with_capacity(6)  =  alloc::string::String
"String".to_string()    = String alloc::string::String
format!("{}", "String") = String alloc::string::String
["Str", "ing"].concat() = String alloc::string::String

[print String methods]
s.push('S'); s.push_str("tring") = String
"String".to_string().len() = 6
"String".to_string().capacity() = 6
"String".to_string().remove(0) = S

今回はここまで。
ここまでで一応基本的な型は終わりです。

1
2
0

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?