相关疑难解决方法(0)

为什么要试试!()和?在不返回Option或Result的函数中使用时不编译?

为什么这段代码不能编译?

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)

rust

42
推荐指数
2
解决办法
7977
查看次数

是问号运算符吗?相当于试试!宏?

我正在寻找一种方法来链接try!Rust 中的宏的使用,并找到实现?运算符的拉取请求.

它似乎已合并,但我似乎无法找到任何文档.是等同于try!宏还是存在重要差异?

operators rust

26
推荐指数
1
解决办法
7483
查看次数

是否有一种非混乱的方式来链接返回Option值的函数的结果?

我有一些看起来像这样的代码:

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,gh返回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)

nullable optional rust

8
推荐指数
2
解决办法
1961
查看次数

您能否返回适用于任何可能的错误类型的结果?

我想使用多个库,每个库都有自己的错误类型。我并不真正关心每个特定板条箱的错误类型,我想使用?习惯用法来使用那些返回类型的板条箱的方法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)

error-handling rust

8
推荐指数
1
解决办法
2495
查看次数

如何忽略从Rust函数返回的错误并继续执行?

当知道某些代码可能会抛出错误时,我们会使用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中使用这样的构造,以确保即使在发生错误之后它仍继续运行.

rust

7
推荐指数
1
解决办法
4018
查看次数

如何检查两个变量是否都是 Some?

我对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)

但是如果我这样做,我总是必须打开paramvalue访问这些值。

我想过这样的事情来避免这种情况。但是这段代码不起作用:

if param == Some(par) && value == Some(val) {
    //process
}
Run Code Online (Sandbox Code Playgroud)

这个想法是这些值可以被版本访问par并且val就像它们在 …

rust

7
推荐指数
2
解决办法
989
查看次数

如何手动返回Result &lt;(),Box &lt;Error &gt;&gt;?

如果条件为真,我想从函数返回错误:

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)

我可能没有类型系统的基础知识,但是在我所看到的所有地方,人们都在使用?运算符,所以我无法弄清楚要返回哪种类型。

  1. 是否可以仅返回这样的错误?
  2. 有没有更好的方法来处理这种逻辑?

error-handling type-systems rust

5
推荐指数
3
解决办法
3491
查看次数

如果借用的结构体字段没有实现复制或克隆特征,那么重用它的最佳方法是什么?

我正在为 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)

ownership rust

5
推荐指数
1
解决办法
1012
查看次数

为什么可以?运算符将 &amp;str 转换为 Box&lt;dyn Error&gt;?

请考虑以下两个函数:

\n
use 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}\n
Run Code Online (Sandbox Code Playgroud)\n

foo()会编译,但是bar()不会\xe2\x80\x99t。

\n

我想我明白为什么bar()\xe2\x80\x99t 不起作用:我们期望一个对象实现Errora 中的特征Box,但我们传递的 a&str既不实现Error也不在 a 中Box

\n

我想知道为什么foo()可以编译。在这种情况下,Won\xe2\x80\x99t?操作员也尝试将 转换&str为 a吗Box<dyn Error>?为什么它能成功?

\n

rust

3
推荐指数
1
解决办法
1401
查看次数

如何返回包含 serde_json::Value 的结果?

这就是我所拥有的,但我想避免使用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)

rust serde

1
推荐指数
1
解决办法
3871
查看次数

匹配 Result&lt;T, E&gt; 时返回错误的最简洁方法是什么?

我正在调用一个返回 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 行样板文件......我只是在寻找一种方法来简化并使其更具可读性。我的愿望是让它在出现错误时返回错误,否则处理结果值。

error-handling rust

1
推荐指数
1
解决办法
6125
查看次数

从 Rust 中的函数返回值有哪些不同的方法?

我遇到了以下两种方式:

#[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)

只有这两种选择吗?

return function rust

0
推荐指数
1
解决办法
103
查看次数