我使用日志包进行一些基本的日志记录,我希望日志消息可以转到文件或stderr。我创建了一个结构来保存输出目标,但得到以下错误:
error: the trait `core::marker::Send` is not implemented for the type `std::io::Write + 'static` [E0277]
impl log::Log for MyLogger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
}
fn log(&self, record: &LogRecord) {
}
...
help: run `rustc --explain E0277` to see a detailed explanation
note: `std::io::Write + 'static` cannot be sent between threads safely
note: required because it appears within the type `Box<std::io::Write + 'static>`
note: required because it appears within the type `MyLogger`
note: required by `log::Log`
这是我用来测试这个代码的代码:
extern crate log;
use log::{LogRecord, LogMetadata, LogLevelFilter, SetLoggerError};
use std::io::{LineWriter, stderr, Write};
use std::fs::OpenOptions;
use std::sync::{Arc, Mutex};
struct MyLogger {
out_stream: Arc<Mutex<Box<Write>>>
}
impl log::Log for MyLogger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
}
fn log(&self, record: &LogRecord) {
}
}
impl MyLogger {
fn init(outfile: String) -> Result<(), SetLoggerError> {
let logfile = match OpenOptions::new().create(true).append(true).open(&outfile) {
Ok(f) => Box::new(LineWriter::new(f)) as Box<Write>,
Err(_) => Box::new(LineWriter::new(stderr())) as Box<Write>
};
log::set_logger(|max_log_level| {
max_log_level.set(LogLevelFilter::Warn);
Box::new(MyLogger{out_stream: logfile})
})
}
}
fn main() {
MyLogger::init("");
}
答案 0 :(得分:2)
The Log
trait是Send
和Sync
的子广告:
pub trait Log: Sync + Send {
fn enabled(&self, metadata: &LogMetadata) -> bool;
fn log(&self, record: &LogRecord);
}
要为您自己的类型实施Log
,您的类型也必须为Send
和Sync
。
但是,您的MyLogger
结构既不是Send
也不是Sync
,因为Box<Write>
可能包含非Send
类型。我们可以将该框限制为包含Send
类型:
struct MyLogger {
out_stream: Arc<Mutex<Box<Write + Send>>>
}
这足以使MyLogger
Send
和Sync
成为extern crate log;
use log::{LogRecord, LogMetadata, LogLevelFilter, SetLoggerError};
use std::io::{LineWriter, stderr, Write};
use std::fs::OpenOptions;
use std::sync::{Arc, Mutex};
struct MyLogger {
out_stream: Arc<Mutex<Box<Write + Send>>>
}
impl log::Log for MyLogger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
unimplemented!()
}
fn log(&self, record: &LogRecord) {
unimplemented!()
}
}
impl MyLogger {
fn init(outfile: &str) -> Result<(), SetLoggerError> {
let logfile = match OpenOptions::new().create(true).append(true).open(outfile) {
Ok(f) => Box::new(LineWriter::new(f)) as Box<Write + Send>,
Err(_) => Box::new(LineWriter::new(stderr())) as Box<Write + Send>
};
log::set_logger(|max_log_level| {
max_log_level.set(LogLevelFilter::Warn);
Box::new(MyLogger { out_stream: Arc::new(Mutex::new(logfile)) })
})
}
}
fn main() {
MyLogger::init("");
}
。以下是您的代码,其中包含此修复程序和其他必要的修复程序:
public static void Load_Image1(string name1, string name2, string name3,string LocationName)
{
var startPath = Application.StartupPath;
string Imagefolder = Path.Combine(startPath, "Image");
string subImageFolder = Path.Combine(Imagefolder, LocationName);
System.IO.Directory.CreateDirectory(subImageFolder);
//string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
List<PictureBox> pictureBoxes = new List<PictureBox>();
pictureBoxes.Add(Image1);
pictureBoxes.Add(Image2);
pictureBoxes.Add(Image3);
using (var wc = new System.Net.WebClient())
{
var uri = ("https://en.wikipedia.org/w/api.php?action=query&prop=imageinfo&format=json&iiprop=url&iiurlwidth=400&titles="+name1+"|"+name2+"|"+name3);
var response = wc.DownloadString(new Uri(uri));
var responseJson = JsonConvert.DeserializeObject<RootObject>(response);
List<string> urls = new List<string>();
foreach (KeyValuePair<string, Pageval> entry in responseJson.query.pages)
{
var url = entry.Value.imageinfo.First().thumburl;
urls.Add(url);
var hash = url.GetHashCode();
string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
var path = Path.Combine(Jpeg, hash.ToString("X") + ".jpg");
wc.DownloadFile(url, path);
}
for (int i = 0; i < pictureBoxes.Count; i++)
{
Image1.SizeMode = PictureBoxSizeMode.StretchImage;
Image2.SizeMode = PictureBoxSizeMode.StretchImage;
Image3.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBoxes[i].Load(urls[i]);
}
}
}
}