読者です 読者をやめる 読者になる 読者になる

エンジニアですよ!

頑張れ俺くん、巨匠と呼ばれるその日まで

Rust メモ 文字列

rust

文字列

&strString がある。

通常の文字列リテラルString ではなく &str. ( staticな生存期間を持つので &'static str. )

Raw String Literal

https://doc.rust-lang.org/reference.html#raw-string-literals

いわゆるヒアドキュメント的なもの。

複数行の文字列を書きたいときとか、エスケープが多くなるときに使える記法。

fn main() {
    let s = r"foo
bar";
    println!("s: {}", s);

    let s2 = r#""foo"
"bar""#;
    println!("s2: {}", s2);
}

https://play.rust-lang.org/?gist=570032ed1f2969b4a83bd2c958e61adc&version=stable&backtrace=0

変換

String&str

&str が要求されている場合は、単に &s でいい

fn print_str(s: &str) {
    println!("str: {}", s);
}

fn main() {
    let s: String = "hoge".to_string();
    print_str(&s);
}

https://play.rust-lang.org/?gist=8735d3d12183b7e3af000db46f0213e3&version=stable&backtrace=0

ドキュメントにある通り、 ToSocketAddr など &str に実装されているトレイトが必要な場合は明示的に変換する必要がある。

変換する場合は

  • &*s
  • s.as_str()

が使える

&strString

to_string が使える

let s: String = "hoge".to_string();

文字列 → 数値 (など)

文字列から数値に変換するには、strparse が使える。

変数に型を明示するか、 parse::<i32>() といった形式で型を指定することで特定の型に変換できる。

変換先にできるのは数値に限らず FromStr を実装しているもの。

fn main() {
    let s = "1";
    
    let i = s.parse::<i32>().unwrap();
    println!("i: {:?}", i);
    
    let u: u32 = s.parse().unwrap();
    println!("u: {:?}", u);
}

https://play.rust-lang.org/?gist=1428b04c59de601c19bbc62fbd935bdb&version=stable&backtrace=0

FromStr を実装すれば自分で定義した構造体にも変換できる

use std::str::FromStr;

#[derive(Debug)]
struct Person {
    age: i32,
    name: String,
}

#[derive(Debug)]
struct PersonParseError;

impl FromStr for Person {
    type Err = PersonParseError; 
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let ss:Vec<&str> = s.split(",").collect();
        if ss.len() != 2 {
            return Err(PersonParseError{});
        }
        let age = match ss[0].parse() {
            Ok(v) => v,
            _ => return Err(PersonParseError{}),
        };
        let name = ss[1].to_string();
        Ok(Person{age: age, name: name})
    }
}

fn main() {
    let s = "32,totem";
    let p: Person = s.parse().unwrap(); 
    println!("{:?}", p);
}

https://play.rust-lang.org/?gist=a69a67aa2888fdaad9a811ad712f45ab&version=stable&backtrace=0

整形

出力するだけなら println! マクロや print! マクロ、 文字列として返すなら format! マクロを使う。

フォーマット文字列が printf 系とは違っている。ドキュメントに詳しく書いてある。

std::fmt - Rust

対応はこうなる。 println!("{}", s)format!("{:?}", x) と使う。

  • {}Display
  • {?}Debug
  • {o}Octal
  • {x}LowerHex
  • {X}UpperHex
  • {p}Pointer
  • {b}Binary
  • {e}LowerExp
  • {E}UpperExp

第一引数にフォーマット文字列を渡すが、ここには変数を渡すことはできなくて文字列リテラルしか渡すことができない。

幅についてはパラメータを渡すことができるので動的に変えることができる。

fn main() {
    println!("'{:0width$}'", 10, width = 5);
}

https://play.rust-lang.org/?gist=fe8190d386e7a4ef0282ababa494a6b1&version=stable&backtrace=0