我只是发现了一些我认为不是那样的东西(事实上我浪费了很多时间来修复它)。
我想在你的帮助下了解我哪里错了,如果我理解正确。
所以我爱上了?
错误处理(我不知道在其他语言中没有它我是如何生活的!)。
但是使用collect()
,我认为是一样的:
pub fn get_players(input: &PlayerInput) -> Result<Option<Vec<Player>>> {
if let Some(input_players) = input.players.as_ref() {
let players: Result<Vec<Player>> = input_players
.iter()
.map(|x| {
Player::new(x.id.as_deref(), &x.code, &x.name)
})
.collect()?;
Ok(Some(players))
} else {
Ok(None)
}
}
错误:
error[E0308]: mismatched types
--> src\player\get.rs:55:17
|
55 | Ok(Some(players))
| ---- ^^^^^^^^ expected struct `Vec`, found enum `Result`
| |
| arguments to this enum variant are incorrect
|
= note: expected struct `Vec<_>`
found enum `Result<Vec<_>, common::error::Error>`
help: the type constructed contains `Result<Vec<Player>, common::error::Error>` due to the type of the argument passed
--> src\player\get.rs:55:12
|
55 | Ok(Some(players))
| ^^^^^--------^
| |
| this argument influences the type of `Some`
所以阅读网页时,我发现我需要使用turbofish语法来使其工作,而不是类型提示,就像这样:
pub fn get_players(input: &PlayerInput) -> Result<Option<Vec<Player>>> {
if let Some(input_players) = input.players.as_ref() {
// let players: Result<Vec<Player>> = input_players
let players = input_players
.iter()
.map(|x| {
Player::new(x.id.as_deref(), &x.code, &x.name)
})
// .collect()?;
.collect::<Result<Vec<Player>>>()?;
Ok(Some(players))
} else {
Ok(None)
}
}
但为什么会这样呢?为什么提示类型在这里不起作用呢?
2条答案
按热度按时间9o685dep1#
使用
?
的事实使编译器变得模糊。多个类型可以使?
适用于返回Result
的函数:你可以编写自己的这样的类型(好吧,它需要nightly,因为Try
trait是实验性的,但它是可能的)。因此,编译器认为你可能正在将collect()
插入一个不同的类型,该类型也实现了FromIterator
和Try
。fnvucqvd2#
如果你使用的是
?
,这段代码需要更新,因为Result
现在被分割成一个返回值,或者Ok
部分被赋值。在?
之后剩下的就是Ok
部分:如果你让编译器只使用
let players = ...
来解决这个问题,它可能会像预期的那样工作。编译器说的是“我不知道如何从这个迭代器中收集
Result
”。你可以在作业上暗示,或者在多宝鱼上暗示,或者两者都暗示,但是如果两者都暗示,他们必须就发生了什么达成一致。
编译器应该能够弄清楚
players
唯一可以是Vec<Player>
,这应该是可行的,但如果不可行,那么就是提示时间了。