11月 15, 2023 LaGee
獲得最大值最小值有三種方法
一個是max、min
一個是max_by、min_by
最後則是max_by_key、min_by_key
這篇[1]有提到max和min
而本文則是會比較三者差別以及介紹_by和_by_key
先比較三者差別,以最大值舉例
fn max(self) -> Option<Self::Item>
where
Self: Sized,
Self::Item: Ord,
fn max_by<F>(self, compare: F) -> Option<Self::Item>
where
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where
B: Ord,
Self: Sized,
F: FnMut(&Self::Item) -> B,
三種都是被歸類在iter下
並且回傳都是Option,裡面包含最大值
不同的是max[2]為一種默認行為
max_by[3]需要使用一個閉包,並且對兩個元素引用
max_by_key[4]則是一樣會使用閉包,但只對一個元素引用
min[5]、min_by[6]、min_by_key[7]同理
比較
以一個程式比較三種打法
let numbers = vec![3, 5, 2, 1, 9, 12, 6];
println!("max: {:?}", numbers.iter().max());
println!("max_by: {:?}", numbers.iter().max_by(|&x, &y| x.cmp(y)));
println!("max_by_key: {:?}", numbers.iter().max_by_key(|&x| x));
println!("min: {:?}", numbers.iter().min());
println!("min_by: {:?}", numbers.iter().min_by(|&x, &y| x.cmp(y)));
println!("min_by_key: {:?}", numbers.iter().min_by_key(|&x| x));
max: Some(12)
max_by: Some(12)
max_by_key: Some(12)
min: Some(1)
min_by: Some(1)
min_by_key: Some(1)
max具有直接默認的特性
max_by需要使用兩個元素,並且比較最大值
max_by_key則是相對直觀,使用一個元素就可以比較最大值
以我目前認知來說,大概是這樣
例子
在大多數情況下,max_by和max_by_key是可以共通的
國外也蠻多人在討論兩個哪邊有"明顯"的不一樣
在我看來,就只是容不容易閱讀的差別
但reddit的這篇文章[8]有提出生命週期的問題
我覺得很有趣,就直接把程式碼放上來了
fn main() {
let items = vec!["zaa".to_string(), "ybb".to_string(), "xbc".to_string()];
// get the max by substring from the 2nd character to the end
// works
// let max = items.into_iter().max_by(|s1, s2| s1[1..].cmp(&s2[1..]));
// error: lifetime may not live long enough
let max = items.into_iter().max_by_key(|s| &s[1..]);
println!("max: {:?}", max);
}error: lifetime may not live long enough
--> src\main.rs:10:48
|
10 | let max = items.into_iter().max_by_key(|s| &s[1..]);
| -- ^^^^^^^ returning this value
requires that `'1` must outlive `'2` ||
| |return type of closure is &'2 str
| has type `&'1 String`
會發現上面的let max可以正常動作
但下面let max則會err
錯誤訊息為生命週期不夠長
Rust編譯器無法判定閉包和String引用哪個生命週期長
只要把into_iter()改成引用iter()就可以了
但生命週期的問題真的太頭痛
到現在也還沒有搞懂
哪天搞懂再寫一篇
參考資料
[1] https://lageeblog.blogspot.com/2023/11/rust-maxmin.html
[2] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.max
[3] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.max_by
[4] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.max_by_key
[5] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min
[6] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by
[7] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by_key
[8] https://www.reddit.com/r/rust/comments/nh5iup/what_is_the_intention_of_the_max_by_iterator/
0 comments:
張貼留言