f64
がborrow()
メソッドを持っていないので、問題のコードはコンパイルされません。また、受け入れるスライスは変更しないので変更する必要はありません。ここでコンパイルして動作します修正版です:
fn mean(arr: &[f64]) -> f64 {
let mut i = 0.0;
let mut mean = 0.0;
for num in arr.iter() {
i += 1.0;
mean += (num - mean)/i;
}
mean
}
は整数を受け入れるには、機能がジェネリックする必要があります。理想的には、整数だけでなく、などのf64
に変換できるタイプまたはユーザー提供のデータタイプを受け入れることが理想的です。 x as f64
を任意x
のために定義されていないので、これはコンパイルされません
fn mean<T>(arr: &[T]) -> f64 {
let mut i = 0.0;
let mut mean = 0.0;
for num in arr.iter() {
i += 1.0;
mean += (num as f64 - mean)/i;
}
mean
}
:次のように書くことがいいだろう。その代わりに、T
の値にT
の値をf64
に変換する方法を定義する特性が必要です。これはまさにInto
traitの目的です。 Into<U>
を実装するすべてのタイプT
はinto(self) -> U
メソッドを定義します。特性バインドとしてT: Into<f64>
を指定するとinto()
メソッドが返され、f64
が返されます。
またT
をCopy
とする必要があります。そのため、Rustは、配列の値が変換によって「消費」(移動)されないことを認識します。整数はCopy
を実装しているので、これは私たちにとっては問題ありません。これが唯一のf64
からロスレス変換を定義するタイプのために働くことを
fn mean<T: Into<f64> + Copy>(arr: &[T]) -> f64 {
let mut i = 0.0;
let mut mean = 0.0;
for num in arr.iter() {
i += 1.0;
mean += ((*num).into() - mean)/i;
}
mean
}
fn main() {
let val1 = mean(&vec![4.0, 5.0, 3.0, 2.0]);
let val2 = mean(&vec![4, 5, 3, 2]);
println!("The means are {} and {}", val1, val2);
}
注:作業するコードは次のようになります。従って、u32
,i32
(上記の例のような)とそれより小さい整数型では動作しますが、i64
またはu64
のベクトルは受け入れられません。これは無損失でf64
に変換できません。
また、この問題は、enumerate()
やfold()
などの関数型プログラミングイディオムにはうまく当てはまることにも注意してください。このような実装を書くことは、すでに長めの答えの範囲外ですが、エクササイズhard to resistです。
"整数で作業する"と言うとき、戻り値の型は何か:整数か浮動小数点か? @MatthieuM。 –
。選択されたアルゴリズムで判断すると、OPはいつも 'f64'を返すものが好きですが、整数入力も受け付けます。 – user4815162342
私が思っていない 'num' crateも不十分だと見てください。例えば、 – user25064