我有以下结构:
struct Age(u8);
struct User {
age: Age,
}
我想将
User
类型的借入值强制转换为&Age
,如以下示例所示:let s = String::from("abcd");
let z: &str = &s; // This works
let b = Box::new(Age(8));
let a: &Age = &b; // This also works
documentation for
Borrow
提到如果A
实现B
,则可以借用A
类型作为其他类型的Borrow<B>
,因此我尝试为Borrow<Age>
实现User
:use std::borrow::Borrow;
impl Borrow<Age> for User {
fn borrow(&self) -> &Age {
&self.age
}
}
fn main() {
let u = User { age: Age(8) };
let a: &Age = u.borrow(); // Works
let a: &Age = &u; // Error
}
这是我收到的错误消息:
error[E0308]: mismatched types
--> src/main.rs:23:19
|
23 | let a: &Age = &u; // Error: expected struct `Age`, found struct `User`
| ^^ expected struct `example::Age`, found struct `example::User`
|
= note: expected type `&example::Age`
found type `&example::User`
我想念什么吗?如何将
&u
强制转换为&Age
? 最佳答案
带有Box
和String
的两个示例的工作不是因为Borrow
特性,而是因为Deref
特性。您可以将示例中的&b
框强制转换为&Age
,因为Box<Age>
实现了Deref<Target = Age>
。同样,String
具有Deref
实现,因此可以将String引用&s
强制转换为&str
。它将以完全相同的方式为您的User
工作:
use std::ops::Deref;
impl Deref for User { // That's bad, don't do that.
type Target = Age;
fn deref(&self) -> &Age {
&self.age
}
}
在此范围内,现在可以编译以下内容:
let u = User { age: Age(8) };
let a: &Age = &u;
请注意,该示例在某种程度上是人为的,而不是惯用的:没有人会期望
User
的行为类似于Age
的指针类型。同样,没有人会期望user.borrow()
借用Age
而不是User
,这不是Borrow
特性的用途。