标准输出 vs 标准错误
- 标准输出:stdout
- println!
- 标准错误:stderr
- eprintln!
标准输出重定向:cargo run > output.txt
- eprintln!
use minigrep::Config;use std::env;use std::process;fn main() {let args: Vec<String> = env::args().collect();let config = Config::new(&args).unwrap_or_else(|err| {eprintln!("Problem parsing arguments: {}", err);process::exit(1);});if let Err(e) = minigrep::run(config) {eprintln!("Application error: {}", e);process::exit(1);}}
use std::env;use std::error::Error;use std::fs;pub fn run(config: Config) -> Result<(), Box<dyn Error>> {let contents = fs::read_to_string(config.filename)?;let results = if config.case_sensitive {search(&config.query, &contents)} else {search_case_insensitive(&config.query, &contents)};for line in results {println!("{}", line);}Ok(())}pub struct Config {pub query: String,pub filename: String,pub case_sensitive: bool,}impl Config {pub fn new(args: &[String]) -> Result<Config, &'static str> {if args.len() < 3 {return Err("not enough arguments");}let query = args[1].clone();let filename = args[2].clone();let case_sensitive = env::var("CASE_INSENSITIVE").is_err();Ok(Config {query,filename,case_sensitive,})}}pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {let mut results = Vec::new();for line in contents.lines() {if line.contains(query) {results.push(line);}}results}pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {let mut results = Vec::new();let query = query.to_lowercase();for line in contents.lines() {if line.to_lowercase().contains(&query) {results.push(line);}}results}#[cfg(test)]mod tests {use super::*;#[test]fn case_sensitive() {let query = "duct";let contents = "\Rust:safe, fast, productive.Pick three.Duct tape.";assert_eq!(vec!["safe, fast, productive."], search(query, contents));}#[test]fn case_insensitive() {let query = "rUst";let contents = "\Rust:safe, fast, productive.Pick three.Trust me.";assert_eq!(vec!["Rust:", "Trust me."],search_case_insensitive(query, contents));}}
