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();
}
,但尽管使用了正确的导入,我仍然会遇到同样的错误。这是因为模块的实现不好吗?
有点?如果查看错误中指定的类型,则handler
是Result<File, Error>
。虽然io::Write
是在File
上实现的,但它没有在Result
上实现。
问题是,当您检查handler.is_err()
时,您永远不会从中获取文件,在出现错误的情况下也不会返回。通常情况下,您会使用类似match
或if let
的方法或其中一种高阶方法(例如Result::map
、Result::and_then
(来处理或传播各种情况。
老实说,整件事相当奇怪和尴尬,例如,你的函数可能会失败,但它们会恐慌(你从来没有真正返回Err
(;如果你打算在打开文件进行写入失败时尝试创建一个文件,为什么不直接这样做呢[0];您手动调用write_fmt
和format_args
,为什么不只是write!
;write_fmt
已经返回一个io::Error
,为什么要丢弃它,然后通过Error::last_os_error
再次请求;等等。
当铁锈生态系统已经有了一堆记录器时,手动滚动你自己的记录器也有点奇怪,尽管你这样做了;命名也有点尴尬,例如,我希望set_X
实际上设置X
,所以对我来说,set_log
将是设置要登录的文件的一种方式。
[0].create(true).append(true)
应在附加模式下打开文件(如果存在(,否则创建文件;更不用说你的版本有并发问题:如果openforappend失败,你可以在写模式下创建文件,但其他人可能在两次调用之间创建了带有内容的文件,在这种情况下,你将部分覆盖文件