Help us understand the problem. What is going on with this article?

Rustのfold

More than 1 year has passed since last update.

ふつうの関数型言語の感覚でfoldすると、参照で詰む。

例題として、任意個の整数の最大公約数の計算を考える。

誤ったコード

fn gcd(a: u32, b: u32) -> u32 {
    assert!(a != 0 || b != 0);
    if a == 0 { b }
    else { gcd(b % a, a) }
}

fn main() {
    let nums = [799459, 28823, 27347];
    if let Some((head, tail)) = nums.split_first() {
        println!("gcd = {}", tail.iter().fold(head, gcd));
    }
}

正しいコード

fn gcd(a: u32, b: u32) -> u32 {
    assert!(a != 0 || b != 0);
    if a == 0 { b }
    else { gcd(b % a, a) }
}

fn main() {
    let nums = [799459, 28823, 27347];
    // &head に注意
    if let Some((&head, tail)) = nums.split_first() {
        // &b に注意
        println!("gcd = {}", tail.iter().fold(head, |a,&b| gcd(a,b)));
    }
}
  • slice::split_firstは参照を返すので、&headで受けて参照を剥がさなければならない
  • foldする関数の第二引数には参照が渡ってくるので、&bで受けて参照を剥がさなければならない

foldに渡す関数の引数と戻り値が参照である場合は、この罠には嵌まらない。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away