首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何强制将`&b‘改为’&A‘for’b:B‘in’`let a:&A=&b;‘?

如何强制将`&b‘改为’&A‘for’b:B‘in’`let a:&A=&b;‘?
EN

Stack Overflow用户
提问于 2019-01-31 17:39:43
回答 1查看 126关注 0票数 2

我有以下结构:

代码语言:javascript
复制
struct Age(u8);
struct User {
    age: Age,
}

我想将User类型的借来的值强制转换为&Age,如下所示:

代码语言:javascript
复制
let s = String::from("abcd");
let z: &str = &s; // This works

let b = Box::new(Age(8));
let a: &Age = &b; // This also works

Borrow提到,A类型可以作为其他类型的B借用,如果A实现了Borrow<B>,所以我尝试为User实现Borrow<Age>

代码语言:javascript
复制
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
}

这是我得到的错误消息:

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-31 18:07:46

使用BoxString的两个示例之所以起作用不是因为Borrow特性,而是因为Deref特性。示例中的框&b可以强制进入&Age,因为Box<Age>实现了Deref<Target = Age>。类似地,String有一个Deref实现,因此可以将字符串引用&s强制转换为&str。它将以完全相同的方式为您的User工作:

代码语言:javascript
复制
use std::ops::Deref;

impl Deref for User { // That's bad, don't do that.
    type Target = Age;
    fn deref(&self) -> &Age {
        &self.age
    }
}

在此范围内,现在可以编译以下内容:

代码语言:javascript
复制
let u = User { age: Age(8) };
let a: &Age = &u;

请注意,这个示例有些人为,而不是惯用的:没有人会期望User的行为像指向Age的指针类型。同样,没有人会期望user.borrow()借用Age而不是User,这不是Borrow特性的目的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54466319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档