为什么在尝试获取对装箱值的引用时得到预期类型 `()`?
Why do I get expected type `()` when trying to obtain a reference to a boxed value?
我有这个结构:
pub struct Node<T> {
value: T,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.unwrap())))
// Some(self.left.unwrap()) <= same result
}
None
}
}
fn main() {}
我收到此错误时似乎类型不匹配:
error[E0308]: mismatched types
--> src/main.rs:10:13
|
10 | Some(&(*(self.left.unwrap())))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::option::Option`
|
= note: expected type `()`
found type `std::option::Option<&Node<T>>`
我是 Rust 的新手,不明白为什么预期的类型是 ()
而它应该是 Option<&Self>
以及我如何 return 对内部节点的引用盒子(怎么才能搬出借来的自己)?
你收到错误是因为 if
块是一个表达式;你需要在它后面加上一个 else
以便函数的输出是正确的 (Option<&Self>
).
此外,您可以利用if let
获取Option
的内在价值;那么很容易从 Box
:
中获取引用
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if let Some(ref left) = self.left { // if let
Some(&*left) // return a reference to the content of the Box (in an Option)
} else {
None // or return None if self.left is None
}
}
}
使用示例:
fn main() {
let test0 = Node {
value: 0,
left: None,
right: None
};
let test1 = Node {
value: 0,
left: Some(Box::new(test0)),
right: None
};
println!("{:?}", test1.getLeft()); // Some(Node { value: 0, left: None, right: None })
}
这里的问题不是借阅检查器。如果您有 if
而没有 else
,则您 必须 return 单位( 即 ()
).您正在尝试 return 函数中的一个值,这意味着您需要有一个 else
分支,或者使用 return
。即:
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.unwrap())))
} else {
None
}
}
}
好的,现在借用检查器出了问题。这是因为您引用的是临时文件(self.left.unwrap()
的结果)。您需要在不移动 的情况下访问 Option
的内容。那么让我们这样做吧:
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.as_ref().unwrap())))
} else {
None
}
}
}
这样更好,但它很丑。有 unwrap
,加上多余的括号,这个名字不合惯用语,最后整个分支本身是不必要的。让我们解决所有这些问题:
impl<T> Node<T> {
pub fn get_left(&self) -> Option<&Self> {
self.left.as_ref().map(|l| &**l)
}
}
或者,如果您想要更清楚的内容:
impl<T> Node<T> {
pub fn get_left(&self) -> Option<&Self> {
if let Some(left) = self.left.as_ref() {
Some(&**left)
} else {
None
}
}
}
我有这个结构:
pub struct Node<T> {
value: T,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.unwrap())))
// Some(self.left.unwrap()) <= same result
}
None
}
}
fn main() {}
我收到此错误时似乎类型不匹配:
error[E0308]: mismatched types
--> src/main.rs:10:13
|
10 | Some(&(*(self.left.unwrap())))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::option::Option`
|
= note: expected type `()`
found type `std::option::Option<&Node<T>>`
我是 Rust 的新手,不明白为什么预期的类型是 ()
而它应该是 Option<&Self>
以及我如何 return 对内部节点的引用盒子(怎么才能搬出借来的自己)?
你收到错误是因为 if
块是一个表达式;你需要在它后面加上一个 else
以便函数的输出是正确的 (Option<&Self>
).
此外,您可以利用if let
获取Option
的内在价值;那么很容易从 Box
:
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if let Some(ref left) = self.left { // if let
Some(&*left) // return a reference to the content of the Box (in an Option)
} else {
None // or return None if self.left is None
}
}
}
使用示例:
fn main() {
let test0 = Node {
value: 0,
left: None,
right: None
};
let test1 = Node {
value: 0,
left: Some(Box::new(test0)),
right: None
};
println!("{:?}", test1.getLeft()); // Some(Node { value: 0, left: None, right: None })
}
这里的问题不是借阅检查器。如果您有 if
而没有 else
,则您 必须 return 单位( 即 ()
).您正在尝试 return 函数中的一个值,这意味着您需要有一个 else
分支,或者使用 return
。即:
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.unwrap())))
} else {
None
}
}
}
好的,现在借用检查器出了问题。这是因为您引用的是临时文件(self.left.unwrap()
的结果)。您需要在不移动 的情况下访问 Option
的内容。那么让我们这样做吧:
impl<T> Node<T> {
pub fn getLeft(&self) -> Option<&Self> {
if self.left.is_some() {
Some(&(*(self.left.as_ref().unwrap())))
} else {
None
}
}
}
这样更好,但它很丑。有 unwrap
,加上多余的括号,这个名字不合惯用语,最后整个分支本身是不必要的。让我们解决所有这些问题:
impl<T> Node<T> {
pub fn get_left(&self) -> Option<&Self> {
self.left.as_ref().map(|l| &**l)
}
}
或者,如果您想要更清楚的内容:
impl<T> Node<T> {
pub fn get_left(&self) -> Option<&Self> {
if let Some(left) = self.left.as_ref() {
Some(&**left)
} else {
None
}
}
}