今年の言語はRust


# 今年の言語はRust

Rustを学びます

![SnapCrab_NoName_2019-4-5_14-19-23_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/62413/e671d07f-d3b7-5cf3-5e0c-641fdeea04c9.png)


勉強ページは日本語ドキュメント

[プログラミング言語Rust](https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/)

目次は6つ

1. はじめる - Rust開発へ向けた環境構築です。
- Rustを学ぶ - 小さなプロジェクトを通してRustについて学びます。
- Effective Rust - 良いRustのコードを書くための高レベルな概念です。
- シンタックスとセマンティクス - Rustについて一歩ずつ、小さく分割しながらやっていきます。
- Nightly Rust - 安定版のRustでは使えないRustの最前線の機能です。
- 用語集 - 本書で使われる用語の参考です。
- 関係書目 - Rustへ影響を与えたもの、Rustに関する論文です。

## 2. 始める

今回はAWS Cloud9上のAmazon Linuxで開発します.

```sh
$ curl https://sh.rustup.rs -sSf | sh

Welcome to Rust.

This script will download the Rust compiler and its package manager, Cargo, and
install them to /usr/local. You may install elsewhere by running this script
with the --prefix=<path> option.

The installer will run under ‘sudo’ and may ask you for your password. If you do
not want the script to run ‘sudo’ then pass it the --disable-sudo flag.

You may uninstall later by running /usr/local/lib/rustlib/uninstall.sh,
or by running this script again with the --uninstall flag.

Continue? (y/N)

```

この章では「rustc」を使ってmain.rsをコンパイルする方法と,
cargoを使ってプロジェクトを管理する方法を学びました.

```sh
$ rustc main.rc
```

```sh
$ cargo new --bin hello_world
$ cargo check
$ cargo build
$ cargo run
$ cargo build --release
```

## 3. Rustを学ぶ

### 3.1 数当てゲーム

数字当てゲームを通して、パッケージの利用、型(mutable)、ループ、比較、stdio、例外処理を学びます.

```rust
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("guess the number!");
    
    let secret_number = rand::thread_rng().gen_range(1, 101);
    
    println!("The secret number is: {}", secret_number);

    loop{
        println!("Please input your guess.");
    
        let mut guess = String::new();
    
        io::stdin().read_line(&mut guess)
            .expect("Failed to read line");
            
        let guess: u32 = match guess.trim().parse(){
                                  Ok(num) => num,
                                  Err(_) => {
                                      println!("Please type a number!!");
                                      continue;
                                  },
                              };

        println!("You guessed: {}", guess);
        
        // ---snip---
        
        match guess.cmp(&secret_number){
            Ordering::Less => println!("Too small"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}


```

### 3.2 食事する哲学者
2つめの例題で非同期処理。

```rust
use std::thread;
use std::time::Duration;
use std::sync::{Mutex, Arc};

struct Philosopher{
    name: String,
    left: usize,
    right: usize,
}

impl Philosopher{
    fn new(name: &str, left: usize, right: usize) -> Philosopher{
    
        Philosopher{
            name: name.to_string(),
            left: left,
            right: right,
        }
    }
    
    fn eat(&self, table: &Table){
        let _left = table.forks[self.left].lock().unwrap();
        thread::sleep(Duration::from_millis(150));
        let _right = table.forks[self.right].lock().unwrap();
        
        
        println!("{} is eating.", self.name);
        
        thread::sleep(Duration::from_millis(1000));
        
        println!("{} is done eating.", self.name);
    }
}

struct Table{
    forks: Vec<Mutex<()>>,
}

fn main() {

    let table = Arc::new(Table{forks: vec![
        Mutex::new(()),
        Mutex::new(()),
        Mutex::new(()),
        Mutex::new(()),
        Mutex::new(()),
    ]});

    let philosophers = vec![
    	Philosopher::new("Judith Butler", 0, 1),
    	Philosopher::new("Gilles Deleuze",1, 2),
    	Philosopher::new("Karl Marx",     2, 3),
    	Philosopher::new("Emma Goldman",  3, 4),
    	Philosopher::new("Michel Foucault",0, 4),
    ];
    
    let handles: Vec<_> = philosophers.into_iter().map(|p|{
        let table = table.clone();
        
        thread::spawn(move || {
            p.eat(&table);
        })
    }).collect();
    
    for h in handles{
        h.join().unwrap();
    }

}

```


## 3.3 多言語と共存

rustのライブラリをpythonから呼び出せた。
これにより高速に実行できた.
並列処理が楽に書けた。

```rust
use std::thread;

#[no_mangle]
pub extern fn process(){
    let handles: Vec<_> = (0..100).map(|_|{
        thread::spawn(|| {
            let mut x = 0;
            for _ in 0..5_000_000 {
                x += 1
            }
            x
        })
    }).collect();
    
    for h in handles {
        println!("Thread finished with count={}",
            h.join().map_err(|_| "Could not join a thread!").unwrap());
    }
}
```

```rust
from ctypes import cdll

lib = cdll.LoadLibrary("target/release/libembed.so");

lib.process();

print("done!");
```


Rust楽しい...!