今年の言語はRust その５５

# 今年の言語はRust その５５

Rustを学びます

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル(英語)
https://doc.rust-lang.org/book/


## 実行環境

```sh
$ cargo -V
cargo 1.33.0 (f099fe94b 2019-02-12)

$ rustup -V
rustup 1.17.0 (069c88ed6 2019-03-05)

$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

$  cat /proc/version
Linux version 4.14.97-74.72.amzn1.x86_64 (mockbuild@gobi-build-64002) 
(gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC)) 
#1 SMP Tue Feb 5 20:59:30 UTC 2019

$ uname -a
Linux ip-10-100-0-8 4.14.97-74.72.amzn1.x86_64 
#1 SMP Tue Feb 5 20:59:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/\*release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Amazon Linux AMI release 2018.03

```

## 19. 高度な機能

通常なら飛ばして後から考えますが、今回は全写経が目的なので、
理解朧げでもひたすら写経して進んでいきます。


### 19.1 Unsafe Rust

Rustには、__Unsafe Rust__ という裏Rustがあるらしい。

（C#でもたまに出てきますね）

#### 生ポインタを参照外しする

```rust

fn main() {

  let mut num = 5;

  let _r1 = &num as *const i32;
  let _r2 = &mut num as *mut i32;

}
```

アドレスを指定してポインタを作ることができる。

しかし、 __safe__　コードではアクセスはできない。


```rust
fn main() {
  let address = 0x012345usize;
  let r = address as *const i32;
}
```

__unsafe__ コードを利用してアクセスする

```rust
fn main () {

  let mut num = 5;

  let r1 = &num as *const i32;
  let r2 = &mut num as *mut i32;

  unsafe {
    println!("{:?}", *r1);
    println!("{:?}", *r2);
  }
}
```

#### unsafeな関数やメソッドを呼ぶ

```rust
unsafe fn dangerous() {
}


fn main() {

  unsafe {
    dangerous();
  }
}

```


#### unsafeコードに安全な抽象化を行う

```rust
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {

  let len = slice.len();

  assert!(mid <= len );

  (&mut slice[..mid], &mut slice[mid..])

}

fn main() {

  let mut v = vec![1,2,3,4,5,6];

  let r = &mut v[..];

  let (a, b) = r.split_at_mut(3);

  assert_eq!(a, &mut [1, 2, 3]);
  assert_eq!(b, &mut [4, 5, 6]);

}

```

```rust
use std::slice;

fn split_at_mut(slice: &mut[i32], mid:usize) -> (&mut[i32], &mut[i32]) {

  let len = slice.len();
  let ptr = slice.as_mut_ptr();

  assert!(mid <= len );

  unsafe {
    ( slice::from_raw_parts_mut(ptr, mid),
      slice::from_raw_parts_mut(ptr.offset(mid as isize), len-mid)
    )
  }
}

fn main() {

  let mut v = vec![1,2,3,4,5,6];

  // unsafeブロックは不要で呼び出せる
  let (a, b) = split_at_mut(&mut v, 3);

  println!("{:?}", a);
  println!("{:?}", b);

  assert_eq!(a, &mut [1, 2, 3]);
  assert_eq!(b, &mut [4, 5, 6]);

}

```

#### extern 関数を使用して外部のコードを呼び出す

RustでCの関数を呼べた！

```rust
extern "C" {
  fn abs(input: i32 ) -> i32;
}


fn main() {
  unsafe {
    println!("Absolute value of -3 according to C: {}", abs(-3));
  }
}
```

CからRustを呼び出す. __#[no_manage]__ を読んで、コンパイラが関数名をマングルしないように指示します。

```rust
#[no_manage]
pub extern "C" fn call_from_c() {
  println!("Just called a Rust function from C!");
}
```

#### 可変で静的な変数にアクセスしたり、変更したりする

Rustではグローバル変数は、static変数と呼ばれる

```rust
static HELLO_WORLD: &str = "Hello, world!";

fn main() {
  println!("name is: {:?}", HELLO_WORLD);
}
```

static変数を改変するには、unsafeである。
これはマルチスレッドの場合に、データ競合になる可能性があるからである。

```rust
static mut COUNTER: u32 = 0;

fn add_to_count(inc: u32) {
  unsafe {
    COUNTER += inc;
  }
}


fn main() {
  add_to_count(3);

  unsafe {
    println!("COUNTER: {:?}", COUNTER);
  }
}
````


#### unsafe なトレイトを実装する


```rust
unsafe trait Foo {

}

unsafe imple Foo for i32 {
  
}
```

長かった。

が、unsafeの大まかな使い方、注意点は勘所が付いた気がする。









イエス！


あと、5/8にRustの最新本がでるみたいです! (現在5/6)

[実践Rust入門[言語仕様から開発手法まで] 単行本（ソフトカバー） – 2019/5/8](https://amzn.to/2VdAQ6y)

<a href="https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Rust%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95%E3%81%BE%E3%81%A7-%CE%BAeen/dp/4297105594/ref=as_li_ss_il?_encoding=UTF8&psc=1&refRID=KADG0R1CJZD9Y07B3P7E&linkCode=li2&tag=peace098beat-22&linkId=52fef8a307968a1010a3375899274077&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4297105594&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=peace098beat-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=peace098beat-22&language=ja_JP&l=li2&o=9&a=4297105594" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

※アフェっときます