为什么这段代码不能编译?
use std::{fs, path::Path};
fn main() {
let dir = Path::new("../FileSystem");
if !dir.is_dir() {
println!("Is not a directory");
return;
}
for item in try!(fs::read_dir(dir)) {
let file = match item {
Err(e) => {
println!("Error: {}", e);
return;
}
Ok(f) => f,
};
println!("");
}
println!("Done");
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误
error[E0308]: mismatched types
--> src/main.rs:11:17
|
11 | for item in try!(fs::read_dir(dir)) {
| ^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
|
= note: expected type `()`
found type `std::result::Result<_, _>`
= note: …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种方法来链接try!Rust 中的宏的使用,并找到实现?运算符的拉取请求.
它似乎已合并,但我似乎无法找到任何文档.是等同于try!宏还是存在重要差异?
我有一些看起来像这样的代码:
f(a).and_then(|b| {
g(b).and_then(|c| {
h(c).map(|d| {
do_something_with(a, b, c, d)
})
})
})
Run Code Online (Sandbox Code Playgroud)
Where f,g和h返回Option值.我需要使用所有的中间值(a,b,c,和d在)do_something_with计算.压痕非常深.有一个更好的方法吗?理想情况下它看起来像这样(当然这不起作用):
try {
let b = f(a);
let c = g(b);
let d = h(c);
do_something_with(a, b, c, d)
} rescue NonexistentValueException {
None
}
Run Code Online (Sandbox Code Playgroud) 我想使用多个库,每个库都有自己的错误类型。我并不真正关心每个特定板条箱的错误类型,我想使用?习惯用法来使用那些返回类型的板条箱的方法Result。
我也不想解开这些值,如果遇到错误,这会导致恐慌。我可能只是想将不同的错误传播?到顶部,并且如果我愿意的话,也许可以选择处理它们或忽略它们。
我不能用 a 做到这一点,std::result::Result<T, E>因为我不知道返回的错误类型(就像我说的,每个板条箱都可以返回自己的错误)。
我知道 Rust 中没有“面向对象”的多态性,但有特征对象。由于在编译时无法知道特征对象的大小,因此我们必须将它们隐藏在某种指针后面,例如&or Box<_>。
错误实现的基本特征似乎是std::error::Error。
我看到的一件事是fn foo() -> Result<Blah, Box<dyn Error>>策略,它利用了特征对象的概念。
这种策略的问题是没有一个包返回装箱错误,这导致编译器抱怨同样的问题。
一个示例用例:
use native_tls::TlsConnector; // 0.2.3
use std::io::{Read, Write};
use std::net::TcpStream;
fn main() {
match do_stuff() {
Ok(string) => {
println!("{}", string);
}
_ => {
println!("Failed!");
}
}
}
fn do_stuff() -> Result<String, Box<(dyn std::error::Error + 'static)>> {
let connector = TlsConnector::new()?;
let stream = TcpStream::connect("jsonplaceholder.typicode.com:443")?;
let …Run Code Online (Sandbox Code Playgroud) 当知道某些代码可能会抛出错误时,我们会使用try/catch块来忽略这些错误并继续.当错误不重要但我们只想记录它时,这样做:
try{
int i = 1/0;
} catch( ArithmeticException e){
System.out.println("Encountered an error but would proceed.");
}
x = y;
Run Code Online (Sandbox Code Playgroud)
Java中的这种构造将继续执行x = y;.
我可以利用match这个或任何其他构造吗?
我确实看到了一个try!宏,但是如果方法的返回类型出现错误,它可能会返回Result.
我想在UT中使用这样的构造,以确保即使在发生错误之后它仍继续运行.
我对Some(T)关键字感到困惑。
我想检查两个变量,如果值已定义(不是None)。如果是这种情况,则处理此变量的值。
我知道match这样工作的模式:
match value {
Some(val) => println!("{}", val),
None => return false,
}
Run Code Online (Sandbox Code Playgroud)
如果我使用这种模式,它会变得非常混乱:
match param {
Some(par) => {
match value {
Some(val) => {
//process
},
None => return false,
}
},
None => return false,
}
Run Code Online (Sandbox Code Playgroud)
这不可能是正确的解决方案。
这是一种可能性,询问参数和值is_some()是否会影响这样的代码:
if param.is_some() && value.is_some() {
//process
}
Run Code Online (Sandbox Code Playgroud)
但是如果我这样做,我总是必须打开param并value访问这些值。
我想过这样的事情来避免这种情况。但是这段代码不起作用:
if param == Some(par) && value == Some(val) {
//process
}
Run Code Online (Sandbox Code Playgroud)
这个想法是这些值可以被版本访问par并且val就像它们在 …
如果条件为真,我想从函数返回错误:
use std::error::Error;
pub fn run() -> Result<(), Box<Error>> {
// -- snip ---
if condition {
// return error
}
// -- snip --
Ok(())
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
我可能没有类型系统的基础知识,但是在我所看到的所有地方,人们都在使用?运算符,所以我无法弄清楚要返回哪种类型。
我正在为 TCP 服务器编写客户端
use std::net::TcpStream;
use std::io::{Read, Write, Error};
pub struct Client {
addr: String,
conn: Option<TcpStream>,
}
impl Client {
pub fn connect(&mut self) {
let res = TcpStream::connect(&self.addr);
match res {
Ok(c) => {
self.conn = Some(c);
},
Err(_) => panic!(),
}
}
pub fn version(self) -> Result<[u8; 8], Error> {
let mut ver: [u8; 8] = [0;8];
let command_string = b"VERSION\r\n";
let res = self.conn.unwrap().write(&command_string[0..]);
match res {
Ok(_) => self.conn.unwrap().read(&mut ver[..]),
Err(e) => panic!(e)
};
Ok(ver) …Run Code Online (Sandbox Code Playgroud) 请考虑以下两个函数:
\nuse std::error::Error;\n\nfn foo() -> Result<i32, Box<dyn Error>> {\n let x: Result<Result<i32, Box<dyn Error>>, &str> = Err("error");\n x?\n}\n\nfn bar() -> Result<i32, Box<dyn Error>> {\n Err("error")\n}\nRun Code Online (Sandbox Code Playgroud)\nfoo()会编译,但是bar()不会\xe2\x80\x99t。
我想我明白为什么bar()\xe2\x80\x99t 不起作用:我们期望一个对象实现Errora 中的特征Box,但我们传递的 a&str既不实现Error也不在 a 中Box。
我想知道为什么foo()可以编译。在这种情况下,Won\xe2\x80\x99t?操作员也尝试将 转换&str为 a吗Box<dyn Error>?为什么它能成功?
这就是我所拥有的,但我想避免使用unwrap我的 reqwest 值:
extern crate base64;
extern crate reqwest;
use serde_json;
use serde_json::json;
pub fn perform_get(id: String) -> serde_json::value::Value {
let client = reqwest::Client::builder().build().unwrap();
let url = String::from("SomeURL");
let res = client.get(&url).send().unwrap().text();
let mut v = json!(null);
match res {
Ok(n) => {
v = serde_json::from_str(&n).unwrap();
}
Err(r) => {
println!("Something wrong happened {:?}", r);
}
}
v
}
fn main() {
println!("Hi there! i want the function above to return a result instead of a Serde value …Run Code Online (Sandbox Code Playgroud) 我正在调用一个返回 a 的函数Result<T, E>,并且我想处理这种Ok情况,但Err如果返回错误则按原样返回。最干净的方法是什么?
例如,我有:
fn example() -> Result<(), Error> {
match foo() {
Ok(v) => bar(v),
Err(e) => Err(e),
}
}
Run Code Online (Sandbox Code Playgroud)
写这个有哪些替代形式?在堆栈中的每次调用中重新包装e另一个感觉很奇怪。Err另外,每个调用基本上都是 4 行样板文件......我只是在寻找一种方法来简化并使其更具可读性。我的愿望是让它在出现错误时返回错误,否则处理结果值。
我遇到了以下两种方式:
#[derive(Debug)]
struct InputList(i32, i32, i32, i32);
#[derive(Debug)]
struct OutputList(i32, i32, i32, i32);
// Option 1
fn foo(input_list: InputList) -> OutputList {
return OutputList(input_list.0, input_list.1, input_list.2, input_list.3);
}
// Option 2
fn bar(input_list: InputList) -> OutputList {
OutputList(input_list.0, input_list.1, input_list.2, input_list.3)
}
fn main() {
let input_list1 = InputList(1, 2, 3, 4);
let input_list2 = InputList(6, 7, 8, 9);
println!("foo() invocation output: {:?}", foo(input_list1));
println!("bar() invocation output: {:?}", bar(input_list2));
}
Run Code Online (Sandbox Code Playgroud)
只有这两种选择吗?