0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

今年の言語はRust その55

Posted at

今年の言語はRust その55

Rustを学びます

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

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

実行環境

$ 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#でもたまに出てきますね)

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


fn main() {

  let mut num = 5;

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

}

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

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

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

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

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な関数やメソッドを呼ぶ

unsafe fn dangerous() {
}


fn main() {

  unsafe {
    dangerous();
  }
}

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

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]);

}

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の関数を呼べた!

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


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

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

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

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

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

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

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

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

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 なトレイトを実装する

unsafe trait Foo {

}

unsafe imple Foo for i32 {
  
}

長かった。

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

イエス!

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

実践Rust入門[言語仕様から開発手法まで] 単行本(ソフトカバー) – 2019/5/8

※アフェっときます

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?