gpt4 book ai didi

rust - 在遍历对 Result 的引用时如何使用问号运算符?

转载 作者:行者123 更新时间:2023-11-29 08:25:50 26 4
gpt4 key购买 nike

我需要分块我的矢量 Vec<Result<SomeStruct>>分成几 block ,遍历每一 block ,做一些工作,如果 Result<SomeStruct> 则返回错误包含它。

enum SomeStruct {}

#[derive(Debug)]
struct SomeError {}

type Result<T> = std::result::Result<T, SomeError>;

fn foo(v: Vec<Result<SomeStruct>>) -> Result<()> {
for chunk in v.chunks(42) {
for value in chunk {
let value = value?;
//do smth with value
}
}
Ok(())
}

fn main() {
let mut values = Vec::new();
foo(values).unwrap();
}

playground

但是,我得到了错误

error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
--> src/main.rs:11:25
|
11 | let value = value?;
| ^^^^^^ the `?` operator cannot be applied to type `&std::result::Result<SomeStruct, SomeError>`
|
= help: the trait `std::ops::Try` is not implemented for `&std::result::Result<SomeStruct, SomeError>`
= note: required by `std::ops::Try::into_result`

好像?期望值本身而不是对值的共享引用,但我无法取消引用共享引用并且不知道如何获取此值本身,因为 chunk这是 &[Result<SomeStruct>] , 和 value&Result<SomeStruct>

我该如何解决?

最佳答案

一般情况

您的函数签名要求您返回一个拥有的 SomeError ,但您所拥有的只是对一个的引用。除非你有一些方法来转换 &SomeError进入SomeError ,这个问题是无解的。

最适用的解决方案是将您的错误更改为可克隆(或可复制,如果适用)然后转换您的 &Result<T, E>进入Result<&T, E>通过 Result::as_ref Result::map_err :

#[derive(Debug, Clone)]
struct SomeError {}
for value in chunk {
let value = value.as_ref().map_err(Clone::clone)?;
// do something with `value`
}

也有可能,但不太常见的是,返回错误的引用。这要求错误的存在时间长于对函数的调用:

type Result<T, E = SomeError> = std::result::Result<T, E>;

fn foo(v: &[Result<SomeStruct>]) -> Result<(), &SomeError> {
for chunk in v.chunks(42) {
for value in chunk {
let value = value.as_ref()?;
// do something with `value`
}
}
Ok(())
}

fn main() {
let values = Vec::new();
foo(&values).unwrap();
}

另见:

具体案例

由于您拥有 Vec 的所有权并且不要利用内部迭代器是一个切片这一事实,您不需要 &Result开始。相反,转换 Vec进入迭代器和take大块长度的片段:

fn foo(v: Vec<Result<SomeStruct>>) -> Result<()> {
let mut v = v.into_iter().peekable();

while v.peek().is_some() {
for value in v.by_ref().take(42) {
let _value = value?;
// do something with `value`
}
}

Ok(())
}

您还可以使用 Itertools::chunks :

use itertools::Itertools; // 0.8.1

fn foo(v: Vec<Result<SomeStruct>>) -> Result<()> {
for chunk in &v.into_iter().chunks(42) {
for value in chunk {
let value = value?;
// do something with `value`
}
}
Ok(())
}

另见:

关于rust - 在遍历对 Result 的引用时如何使用问号运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58922744/

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