gpt4 book ai didi

loops - 发生错误时循环的正确方法是什么

转载 作者:行者123 更新时间:2023-12-03 11:29:34 24 4
gpt4 key购买 nike

我对 Rust 还是很陌生,我仍在努力确保我理解做一个小项目的原则,创建一个使用 TcpStream 的服务器。服务器向客户端请求代码,该代码必须为 8 个字符长。如果不是,它将再次要求输入新代码。这是我到目前为止所拥有的:


fn loby_matcher(stream: &mut TcpStream) -> std::io::Result<(String, usize), >{
let mut game_code = String::new();
let mut reader = BufReader::new(stream);
let len : usize = reader.read_line(&mut game_code)?;
match len {
8 => len,
_ => return Err(Error::new(ErrorKind::Other, "wrong game code")),
};
Ok((game_code, len))
}

pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()>{
println!("Creating a new game! Waiting for the code.");
let game_code: String;
let len: usize;
loop {
(game_code, len) = match loby_matcher(&mut stream) {
Ok(game_code) => break (game_code, len),
Err(e) => {
stream.write("Wrong code\n".as_bytes());
(String::new(),0)
}
};
};
println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}

fn start_server(address: &str, port: &str) -> std::io::Result<()>{
let listener = TcpListener::bind(format!("{}:{}", address, port))?;

for stream in listener.incoming() {
// not using ? as we do not want to stop the server for wrong connection
let stream = stream.unwrap();
thread::spawn(move || {
create_game_matcher(stream);
});
}
Ok(())
}

发生错误时要求新代码的循环似乎是错误的,但我想不出这样做的方法。
此外,我知道我应该创建一个自定义错误,以便能够在我的 TCPstream 上区分错误代码和 I/O 错误,我稍后会这样做。
发生特定错误时,正确的循环方式是什么?
编辑
如果您发现代码中有任何错误,请不要犹豫,告诉我如何改进它。

最佳答案

我假设您是在问如何解决 create_game_matcher 中的问题.如果是这样,那么你需要将你的任务移到更远的地方。
比较 io::Error 里面的错误,可能很麻烦。您可以使用 e.kind() == ErrorKind::Other 检查种类.然而,实际的错误可能是任何东西,并且不需要实现 PartialEq&str .最简单的可能就是做 e.to_string() == "wrong game code" .
但就像你提到的,最惯用的方法是创建一个你自己的错误类型。

pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()> {
println!("Creating a new game! Waiting for the code.");

let (game_code, len) = loop {
match loby_matcher(&mut stream) {
Ok(game_code) => break game_code,
// Err(e) if e.kind() == ErrorKind::Other && e.to_string() == "wrong game code" => {
// or just (for ease of use)
Err(e) if e.to_string() == "wrong game code" => {
stream.write("Wrong code\n".as_bytes())?;
}
Err(e) => return Err(e),
};
};

println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}
因为你想循环直到 loby_matcher成功,然后 (String::new(), 0)可以删除。你也忘了检查是否 stream.write失败,所以我添加了 ? .

或者,鉴于你总是在分配后休息,你也可以这样表达:
pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()> {
println!("Creating a new game! Waiting for the code.");

let game_code: String;
let len: usize;
loop {
match loby_matcher(&mut stream) {
Ok((game_code_, len_)) => {
game_code = game_code_;
len = len_;
break;
}
Err(e) if e.to_string() == "wrong game code" => {
stream.write("Wrong code\n".as_bytes())?;
}
Err(e) => return Err(e),
};
}

println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}

关于loops - 发生错误时循环的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65610824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com