一些错误 E0425 和 E0599 write_fmt


mod loginfo{
use std::io::Error;
use chrono::prelude::*;
use std::io::prelude::*;
use std::fs::OpenOptions;
const LOG_SYS :&'static str = "log.txt";
const LOG_ERR :&'static str = "log_error.txt";
pub fn set_log_error(info: String)->Result<(), String>{
let mut handler = OpenOptions::new().append(true)
.open(LOG_ERR);
if handler.is_err(){
create_file(LOG_ERR.to_owned()).unwrap();
set_log_error(info).unwrap();
}
if let Err(_errno) = handler.write_fmt(
format_args!("{:?}t{:?} ->[Last OS error({:?})]n",
Utc::now().to_rfc2822().to_string(), info,
Error::last_os_error()) ){
panic!(
"nCannot write info log errort Infot:{:?}n",
Error::last_os_error()); 
}
Ok(())
}
pub fn set_log(info: String)->Result<(), String>{
let mut handler = OpenOptions::new().append(true)
.open(LOG_SYS);
if handler.is_err(){
set_log_error("Cannot write info log".to_owned())
.unwrap();
}
if let Err(_errno) = handler.write_fmt(
format_args!("{:?}t{:?}n",
Utc::now().to_rfc2822().to_string(), info)){
set_log_error("Cannot write data log file".to_owned())
.unwrap();       
}
Ok(())
}
pub fn create_file(filename : String)->Result<(), String>{
let handler = OpenOptions::new().write(true)
.create(true).open(filename);
if handler.is_err(){
panic!(
"nCannot create log filet Infot:{:?}n",
Error::last_os_error());
}
Ok(())
}
}

编译时,我得到以下错误:;错误[E0599]:在当前作用域中找不到枚举std::result::Result<std::fs::File, std::io::Error>的名为write_fmt的方法-->src/loginfo.rs:19:38`;

但是,尽管使用了正确的导入,我仍然会遇到同样的错误。这是因为模块的实现不好吗?提前感谢你的回答和发言?


+1@Masklinn好的,我想我明白只写会更容易

pub fn foo_write_log( info: String){
let mut handler = OpenOptions::new().append(true)
.create(true).open(LOG_SYS).expect("Cannot create log");
handler.write_fmt(
format_args!("{:?}t{:?} ->[Last OS error({:?})]n",
Utc::now().to_rfc2822().to_string(), info,
Error::last_os_error())).unwrap();
}

,但尽管使用了正确的导入,我仍然会遇到同样的错误。这是因为模块的实现不好吗?

有点?如果查看错误中指定的类型,则handlerResult<File, Error>。虽然io::Write是在File上实现的,但它没有在Result上实现。

问题是,当您检查handler.is_err()时,您永远不会从中获取文件,在出现错误的情况下也不会返回。通常情况下,您会使用类似matchif let的方法或其中一种高阶方法(例如Result::mapResult::and_then(来处理或传播各种情况。

老实说,整件事相当奇怪和尴尬,例如,你的函数可能会失败,但它们会恐慌(你从来没有真正返回Err(;如果你打算在打开文件进行写入失败时尝试创建一个文件,为什么不直接这样做呢[0];您手动调用write_fmtformat_args,为什么不只是write!write_fmt已经返回一个io::Error,为什么要丢弃它,然后通过Error::last_os_error再次请求;等等。

当铁锈生态系统已经有了一堆记录器时,手动滚动你自己的记录器也有点奇怪,尽管你这样做了;命名也有点尴尬,例如,我希望set_X实际上设置X,所以对我来说,set_log将是设置要登录的文件的一种方式。

[0].create(true).append(true)应在附加模式下打开文件(如果存在(,否则创建文件;更不用说你的版本有并发问题:如果openforappend失败,你可以在写模式下创建文件,但其他人可能在两次调用之间创建了带有内容的文件,在这种情况下,你将部分覆盖文件