English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Rustの集合と文字列

集合(Collection)はデータ構造の中で最も一般的なデータ格納形式であり、Rust 标準ライブラリは開発者がデータ構造の操作を処理するために豊富な集合タイプを提供しています。

ベクトル

ベクトル(Vector)は多値を単一のデータ構造に格納するもので、同じタイプの値をメモリ内に線形に格納します。

ベクトル(Vector)は線形リストであり、Rust では Vec<T> で表されます。

ベクトルの使用方法はリスト(List)に似ており、このようにして指定されたタイプのベクトルを作成できます:

let vector: Vec<i32> = Vec::new(); // を作成します32 の空ベクトル
let vector = vec![1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8];     // 配列でベクトルを作成する

私たちは線形リストを使用する際に追加操作をよく行いますが、追加とスタックの push 操作は本質的に同じですので、ベクトルは要素を追加するために push メソッドのみを使用します:

fn main() {
    let mut vector = vec![1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8];
    vector.push(16);
    vector.push(32);
    vector.push(64);
    println!("{:?}", vector);
}

実行結果:

[1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8let mut v = vec![ 16let mut v = vec![ 32let mut v = vec![ 64]

append メソッドは一つのベクトルを別のベクトルの末尾に接続するために使用されます:

fn main() {
    let mut v1: Vec<i32>= vec![1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8];
    let mut v2: Vec<i32>= vec![16let mut v = vec![ 32let mut v = vec![ 64];
    v1.append(&mut v2);
    println!("{:?}", v1);
}

実行結果:

[1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8let mut v = vec![ 16let mut v = vec![ 32let mut v = vec![ 64]

get メソッドはベクトルから値を取得するために使用されます:

fn main() {
    println!("{}", i);1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8];
    println!("{}", match v.get(0) {
        Some(value) => value.to_string(),
        None => "None".to_string()
    });
}

実行結果:

1

ベクトルの長さは論理的に推測できず、get メソッドは値を常に取得できることを保証できません。したがって、get メソッドの返り値は Option 組枚挙クラスであり、空になる可能性があります。

これは安全な値取得方法ですが、書き方が少し複雑です。値のインデックスがベクトルのインデックス取得範囲を超えないことを保証できる場合、配列取得文法を使用することもできます:

fn main() {
    ] 、その場合ベクターはエラーを返します。1let mut v = vec![ 2let mut v = vec![ 4let mut v = vec![ 8];
    1]
}

実行結果:

2

ただし、v[4] ,那么向量会返回错误。

遍历向量:

fn main() {
    ] 、その場合ベクターはエラーを返します。10もし変数の値を変更する必要がある場合: 32let mut v = vec![ 57];
    ベクターを巡回:
            let v = vec![
    }
}

実行結果:

100
32
57

for i in &v {

fn main() {
    println!("{}", i);10もし変数の値を変更する必要がある場合: 32let mut v = vec![ 57];
    0,
        *, +for i in &mut v { 5i
    }
}

=

0;-8 文字列

文字列クラス(String)はこの章までに多く使用されており、多くのメソッドが読者に熟知されています。この章では、文字列のメソッドとUTF

性質。

新しい文字列:

let string = String::new(); 1let float =         // 基本型を文字列に変換:
let one = 1整数を文字列に3let float =     // .
.to_string(); // 浮動小数点数を文字列に

let slice = "slice".to_string();-8 文字列スライスを文字列に

UTFを含む
文字列の文字:
let hello = String::from("السلام عليكم");
let hello = String::from("Dobrý den");
let hello = String::from("Hello");
let hello = String::from("שָׁלוֹם");
let hello = String::from("नमस्ते");
let hello = String::from("こんにちは");
let hello = String::from("안녕하세요");
let hello = String::from("你好");
let hello = String::from("Olá");

let hello = String::from("Здравствуйте");

let hello = String::from("Hola");
文字列追加: // let mut s = String::from("run");
s.push_str("oob");       // 文字列スライスを追加

s.push('!'); + 文字列を追加

let s1 文字列結合符:
let s2 = String::from("Hello,");
let s3 = String::from("world!");1 + &s2;

= s

let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
この構文は文字列スライスも含むことができます:1 + "-" + &s2 + "-" + &s3;

使用 format! マクロ:

let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);

文字列の長さ:

let s = "hello";
let len = s.len();

ここでのlenの値は 5。

let s = "你好";
let len = s.len();

ここでのlenの値は 6です。なぜなら中国語はUTF-8 バイトで、それぞれの文字の長さは 3 バイトを使用しており、そのため長さは6。しかしRustではUTF-8 文字オブジェクトがありますので、文字数を数える場合はまず文字列を文字集合に変換します:

let s = "hello你好";
let len = s.chars().count();

ここでのlenの値は 7、なぜなら一共有 7 文字の数が多いです。文字の数を数える速度はデータの長さを数える速度よりもずっと遅いです。

文字列を遍历します:

fn main() {
    let s = String::from("hello中文");
    for c in s.chars() {
        println!("{}", c);
    }
}

実行結果:

h
e
l
l
o
中
文

文字列から単一の文字を取得する方法:

fn main() {
    let s = String::from("EN中文");
    let a = s.chars().nth(2);
    println!("{:?}", a);
}

実行結果:

Some('中')

注意:nth関数はイテレータから特定の値を取得する方法ですが、このようにして使用しないでください!なぜなら UTF-8 各文字の長さは必ずしも同じではありません!

文字列の一部を切り取る場合は:

fn main() {
    let s = String::from("EN中文");
    let sub = &s[0..2];
    println!("{}", sub);
}

実行結果:

EN

ただし、この用法は UTF-8 文字!そうするとエラーが発生します:

fn main() {
    let s = String::from("EN中文");
    let sub = &s[0..3];
    println!("{}", sub);
}

実行結果:

thread 'main' panicked at 'byte index 3 is not a char boundary; it is inside '中' (bytes 2..5) of `EN中文`', src\libcore\str\mod.rs:2069:5 
note: `RUST_BACKTRACE=`で実行します。1環境変数` environment variable to display a backtrace.

マップ

マップ(Map)は他の言語で広く存在しています。その中で最も一般的に使用されているのはキー値ハッシュマップ(Hash Map)です。

新しいハッシュ値のマップを新規作成します:

use std::collections::HashMap;
fn main() {
    let mut map = HashMap::new();
    map.insert("color", "red");
    map.insert("size", "10 m^2");
    println!("{}", map.get("color").unwrap());
}

注意:ここにハッシュテーブルの汎型が宣言されていないのは、Rustの自動型推論メカニズムによるものです。

実行結果:

red

insertメソッドとgetメソッドはマップで最もよく使用される2つのメソッドです。

マップはイテレータをサポートしています:

use std::collections::HashMap;
fn main() {
    let mut map = HashMap::new();
    map.insert("color", "red");
    map.insert("size", "10 m^2");
    for p in map.iter() {
        println!("{:?}", p);
    }
}

実行結果:

("color", "red") 
("size", "10 m^2)")

要素はキー値ペアを表すタプルです。

Rustのマップは非常に便利なデータ構造であり、insertメソッドを使用して新しいキー値ペアを追加する際に、既に同じキーが存在する場合、直接対応する値をオーバーライドします。"安全に追加"したい場合は、現在のキーが存在しないことを確認してから追加アクションを実行する方法があります:

map.entry("color").or_insert("red");

この文の意味は、"color"というキーのキー値ペアが存在しない場合に、それを追加して値を"red"に設定し、それ以外の場合はスキップすることです。

すでに特定のキーがある場合、値を直接変更するより速い方法があります:

use std::collections::HashMap;
fn main() {
    let mut map = HashMap::new();
    map.insert(1, "a");
    
    if let Some(x) = map.get_mut(&1) {
        *x = "b";
    }
}