我想围绕现有类型/ struct 创建一个包装器.根据新类型模式,根据Rust Book ch 19,"在包装器上实现Deref-trait以返回内部类型将提供对所有底层方法的访问":

https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

下面是我在字符串包装器上的实现.一个简单的例子:

struct Wrapper(String);

impl Deref for Wrapper {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0 //pointer to Inner value
    }
}

但是,调用消耗self的方法会引发错误:

fn main() {
    let d = "Dog".to_string();
    let w = Wrapper(d);
    w.into_bytes();
}

错误:cannot move out of dereference of 100 move occurs because value has type 101, which does not implement the 102 trait

因此,我有两个问题:

  1. 我的实现有什么问题?如何使其工作?
  2. 我想让它与self一起正常工作;self,mut self,&mut self方法.我如何适当地实现DerefMut?

推荐答案

我的实现有什么问题?如何使其工作?

String::into_bytes移动String,在你的情况下,你只能访问它的引用&,所以你不能移动它.

可以使用bytes将迭代器返回到字节,而不移动它:

fn main() {
    let d = "Dog".to_string();
    let w = Wrapper(d);
    let b = w.bytes();
    println!("{b:?}");
}

我想让它与self一起正常工作;self,mut self,&;mut self方法.我如何适当地实现DerefMut?

一般来说,你需要考虑签名:

  • Deref->;拿到&T
  • DerefMut->;拿到&mut
  • From/Into->;将该类型转换为其他类型T的自有版本

使用From/Into的示例:

struct Wrapper(String);

impl From<Wrapper> for String {
    fn from(w: Wrapper) -> String {
        w.0
    }
}

fn main() {
    let d = "Dog".to_string();
    let w = Wrapper(d);
    let s: String = w.into();
    let bytes = s.into_bytes();
    println!("{bytes:?}");
}

Playground

你也可以考虑看看std::borrow模块,它的特点是允许你像其他类型一样使用你的类型.

最后,您的方法可能有效,但如前所述,在这种情况下,您不能从&TU(您可以从TU).剩下的解决方案是使用Clone并创建一个自有副本:

use std::ops::Deref;

struct Wrapper(String);

impl Deref for Wrapper {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0 //pointer to Inner value
    }
}

fn main() {
    let d = "Dog".to_string();
    let w = Wrapper(d);
    let b = w.deref().clone().into_bytes();
    println!("{b:?}");
}

Playground

Rust相关问答推荐

如何仅使用http机箱发送http请求?

使用 struct 外部的属性来改变 struct 的原始方式

从Type::new()调用函数

如何编写一个以一个闭包为参数的函数,该函数以另一个闭包为参数?

如何修复数组中NewType导致的运行时开销

作为1字节位掩码的布尔值 struct

在0..1之间将U64转换为F64

在Rust 中移动原始指针的靶子安全吗

Rust 中多个 & 符号的内存表示

如何在 Rust 中将 Vec> 转换为 Vec>?

不能将 `*self` borrow 为不可变的,因为它也被borrow 为可变的 - 编译器真的需要如此严格吗?

在运行时在 Rust 中加载字体

是否可以在 Rust 中的特定字符上实现特征?

Rust 异步和 AsRef 未被发送

发生移动是因为 `data` 的类型为 `Vec`,它没有实现 `Copy` 特性

我如何将特征作为 struct 的拥有字段?

使用泛型作为关联类型,没有幻像数据

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

如何制作具有关联类型的特征的类型擦除版本?

来自外部函数的future 内部可变引用