Tôi có một chức năng hoạt động, nhưng chuyên môn hơn tôi muốn và có một số thiếu hiệu quả, tôi muốn khắc phục điều đó.Làm thế nào tôi có thể làm cho chức năng Rust của tôi trở nên chung chung và hiệu quả hơn?
Chức năng thiếu sót làm việc nhưng:
fn iter_to_min<T>(i:T) -> i64 where T:Iterator<Item=String>{
i.collect::<Vec<String>>()
.iter()
.flat_map(|s|s.split_whitespace())
.map(str::trim)
.map(str::parse::<i64>)
.map(Result::unwrap)
.min()
.expect("No min found.")
}
Những lý do tôi không thích điều này thực hiện là:
i64
được cứng mã hóa và tôi muốn tái sử dụng chức năng này chou64
và có thể trở lại khác các loại- nó thu thập thông tin đầu vào của nó chỉ để lặp qua nó ngay lập tức không hiệu quả (phân bổ đống không có lý do)
- việc đóng cửa truyền cho
flat_map
có thể không được tối ưu hóa đi bởi LLVM trong mọi trường hợp
và gần nhất tôi có thể nhận được tới chức năng lý tưởng của tôi:
use std::str::FromStr;
fn iter_to_min<T,U>(i:T) -> U where T:Iterator<Item=String>,U: Ord+FromStr{
i.flat_map(str::split_whitespace)
.map(str::trim)
.map(str::parse::<U>)
.map(Result::unwrap)
.min()
.expect("No min found.")
}
Những vấn đề tôi đang gặp là:
- đối số được chuyển đến
str::split_whitespace
làString
và sẽ không ép buộc vàostr
- đối số truyền cho
str::split_whitespace
không biết sống đủ lâu Result::unwrap
không phàn nàn rằng đặc tínhcore::fmt::Debug
không được thực hiện cho các loại<U as core::str::FromStr>::Err
Tôi nghĩ rằng với ký hiệu đời thông minh và yêu cầu Trait tại ít nhất hai trong số đó có thể được sửa chữa, và ai biết có thể có một cách để đi ba cho ba.
Ví dụ mã sử dụng một số các bản sửa lỗi đề nghị:
use std::io::BufRead;
use std::str::FromStr;
use std::fmt::Debug;
fn iter_to_min<T,U>(i:T) -> U where T:Iterator<Item=String>,U: Ord+FromStr, U::Err: Debug{
i.collect::<Vec<String>>()
.iter()
.flat_map(|s|s.split_whitespace())
.map(str::trim)
.map(str::parse::<U>)
.map(Result::unwrap)
.min()
.expect("No min found.")
}
fn main() {
let a: Vec<_> = std::env::args().skip(1).collect();
let m:i64 = if a.is_empty() {
let s = std::io::stdin();
let m = iter_to_min(s.lock().lines().map(Result::unwrap));
m
}else{
iter_to_min(a.into_iter())
};
println!("{}", m);
}
Nó sẽ là tuyệt vời nếu bạn có thể đăng một ví dụ hoàn chỉnh, tối thiểu mà tôi có thể dán vào một tập tin cục bộ để có được và chạy :) –