[Rustlings] errors6.rs

主要是要練習如何撰寫及應用 error conversion。

Conversion 的部份很單純:

impl ParsePosNonzeroError {
    fn from_creation(err: CreationError) -> ParsePosNonzeroError {
        ParsePosNonzeroError::Creation(err)
    }

    fn from_parsing(err: ParseIntError) -> ParsePosNonzeroError {
        ParsePosNonzeroError::ParseInt(err)
    }
}

比較有趣的是應用的部份。

解法一

用 pattern match。無趣了點,但至少很清楚。

fn parse_pos_nonzero(s: &str)
    -> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
{
    let x = match s.parse() {
        Ok(i) => i,
        Err(e) => return Err(ParsePosNonzeroError::from_parsing(e)),
    };
    PositiveNonzeroInteger::new(x)
        .map_err(ParsePosNonzeroError::from_creation)
}

解法二

利用 ? 簡化解法一。重點是要先做完 map_err() 後才加 ?

fn parse_pos_nonzero(s: &str)
    -> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
{
    let x = s.parse().map_err(ParsePosNonzeroError::from_parsing)?;
    PositiveNonzeroInteger::new(x)
        .map_err(ParsePosNonzeroError::from_creation)
}

解法三

想要用一個 expression 解決?這不就來了嗎?用 and_then() 來串接。

fn parse_pos_nonzero(s: &str)
    -> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
{
    s.parse()
        .map_err(ParsePosNonzeroError::from_parsing)
        .and_then(|x| {
            PositiveNonzeroInteger::new(x)
                .map_err(ParsePosNonzeroError::from_creation)
        })
}

[Exercism][Rust] Parallel Letter Frequency

題目網址(需登入 Exercism)

簡單來說,就是要用 concurrency 的方式,將「計算文章中每個字母(數字和標點不計)出現的次數」,分配給 worker_count 個 thread 去做,最後再整合在一起。

輸入的資料,第一個是 &str 的 array slice,第二個是 worker_count

Continue reading  

[Exercism][Rust] Diffie Hellman

題目網址(需登入 Exercism)

這個題目在 Rust 語言方面,沒有什麼太困難的地方。所以重點都是在 modular arithmetic 的運算上。

use rand::Rng;

pub fn private_key(p: u64) -> u64 {
    let mut rng = rand::thread_rng();
    rng.gen_range(2..p)
}

pub fn public_key(p: u64, g: u64, a: u64) -> u64 {
    modular_exp(g, a, p)
}

pub fn secret(p: u64, b_pub: u64, a: u64) -> u64 {
    modular_exp(b_pub, a, p)
}
Continue reading