C++とRustを比較する

C++やってるけど、「Rustって安全だよ」って言われて興味を持った人向け。
用語はC++視点で。

関数に文字列を渡す

C++

#include <iostream>

void say(std::string str){
    std::cout << "say: " << str << std::endl;
}

int main()
{

    auto str = "hello";
    say(str);
    std::cout << "main: " << str << std::endl;

}

Output

say: hello
main: hello

Rust

fn say(str: String){
    println!("say: {}", str);
}

fn main() {

    let str = String::from("hello");
    say(str);
    println!("say: {}", str);

}

error[E0382]: borrow of moved value: str

  --> src/main.rs:10:25
   |
8  |     let str = String::from("hello");
   |         --- move occurs because `str` has type `std::string::String`, which does not implement the `Copy` trait
9  |     say(str);
   |         --- value moved here
10 |     println!("say: {}", str);
   |                         ^^^ value borrowed here after move

Rustでは参照ではない値に渡すと所有権が移動する(say呼び出しの時点でmainではstrが使えなくなる)

Rustに黙らせるコード(参照で渡す)

fn say(str: &String){
    println!("say: {}", str);
}

fn main() {

    let str = String::from("hello");
    say(&str);
    println!("say: {}", str);

}

Rustに黙らせるコード(所有権を返してもらう)

Rustは代入時に文字列を勝手に再確保&コピーしたりしません。

fn say(str: String) -> String{
    println!("say: {}", str);
    str
}

fn main() {

    let str = String::from("hello");
    let str = say(str); //シャドーイングと言って、同名で上書きできる
    println!("say: {}", str);

}

逆にRustっぽいことを、C++で書いてみる

所有権を1つに限定する(C++11以上)

#include <iostream>
#include <memory>
#include <utility>


std::unique_ptr<std::string> say(std::unique_ptr<std::string> str){
    std::cout << "say: " << *str << std::endl;
    return str;
}


int main()
{

    std::unique_ptr<std::string> str(new std::string("hello"));

    auto str2 = say(std::move(str));

    std::cout << "str@main: " << str << std::endl;

    //コメントアウトしないと落ちます
    //std::cout << "*str@main: " << *str << std::endl;
    std::cout << "*str2@main: " << *str2 << std::endl;

    return 0;
}

Output

say: hello
str@main: 0x0
*str2@main: hello

C++では

    unique_ptrを使っても、コメントアウトした行のようにアクセスが可能、そして死ぬ
bannerAds