1
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 その35

Posted at

今年の言語はRust その35

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

13. 関数型言語の機能: イテレータとクロージャ

13.1 クロージャ: 環境をキャプチャできる匿名関数

ジェネリック引数とFnトレイトを使用してクロージャを保存する

メモ化パターン または、 遅延評価パターン をやります

結果の値が必要な場合のみにその構造体はクロージャを実行し、その結果の値をキャッシュするので、残りのコードは、 結果を保存し、再利用する責任を負わなくて済むのです。このパターンは、メモ化(memoization)または、 遅延評価(lazy evaluation)として知っているかもしれません。

struct Cacher<T>
    where T: Fn(u32) -> u32 
{
      calculation: T,
      value: Option<u32>,
}


impl<T> Cacher<T>
    where T: Fn(u32) -> u32
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            value: None,
        }
    }
    
    fn value(&mut self, arg: u32) -> u32 {
        match self.value {
            Some(v) => v,
            None => {
                let v = (self.calculation)(arg);
                self.value = Some(v);
                v
            },
        }
    }
}

これはコーディング始めたばかりの頃だと、混乱してしまうやつだな

そして、クロージャを使うよ!

前回作っていた、関数をメモ化しました!

なんて便利なんだ!

この、コードはスニペット化して永久保存だな

fn generate_workout(intensity: u32, random_number: u32){

// 前回のただの関数
//   let expensive_closure = |num:u32| -> u32 {
//         println!("calculating slowly...");
//         thread::sleep(Duration::from_secs(2));
//         intensity
//   };
   
   let mut expensive_result = Cacher::new(|num| {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
   });
   
   
   if intensity < 25 {
       println!(
            "Today, do {} pushups!",
            expensive_result.value(intensity)
       );
       
       println!(
            "Next, do {} situps!",
            expensive_result.value(intensity)
       );
   } else {
       if random_number == 3 {
            println!("Take a break today! ");
       } else {
           println!(
                "Today, run for {} min",
                expensive_result.value(intensity)
            );
       }
   }
}

HashMapを使って、値を記録する

さぁ、初めての自分での実装.

コンパイラに助けてもらい何とかできました。
HashMap::get(&arg)等の参照渡しが慣れが必要ですね。。

impl<T> Cacher<T>
    where T: Fn(u32) -> u32
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            caches: HashMap::new()
        }
    }
    
    fn value(&mut self, arg: u32) -> u32 {
    
        match self.caches.get(&arg) {
            Some(v) => *v,
            None => {
                let v = (self.calculation)(arg);
                self.caches.insert(arg, v);
                v
            },
        }
    
    }
}

この章は、永久コピペですね!

イエス!

1
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
1
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?