我具有以下结构:
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>
类型,因此我尝试实现{{1 }} 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
?
答案 0 :(得分:3)
使用Box
和String
的两个示例并不是因为Borrow
特性,而是因为Deref
特性。您的示例中的框&b
可以强制插入&Age
中,因为Box<Age>
实现了Deref<Target = Age>
。同样,String
具有Deref
的实现,因此可以将字符串引用&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
特性的目的。