struct test<'a> {
    name: &'a str
}

impl<'a> test<'a> {
    fn modify_name(&'a mut self) {
        let new_name = self.name.replacen("az", "", 1);
        // i want to add this name to self with the same lifetime as self
        self.name = &'a new_name[..];
    }
}

不允许像上面这样的生命周期,如果我没有指定str的生命周期,rust会在函数结束后删除它. 也不能解引用self.name,因为"str在编译时不能被知道.

我try 在网上查找,但只找到了使用字符串而不是&amp;str的建议.

我想知道是否可以修改引用的 struct 字段. (我在 struct 中使用了很多&amp;str,很少修改它们,所以我更喜欢使用&amp;str)

我不确定这是否可能.如果不是,请向我解释,我遗漏了什么?

推荐答案

1您可以在不更改test的定义的情况下执行此操作的only方法是将其设置为leak a String.这为您提供了一个具有'static生存期的引用,它将被自动强制为更短的生存期.

然而,这显然不是很理想,因为堆分配never将被释放,直到程序终止.如果在循环中运行此函数,您将能够观察到程序的内存使用量随着时间的推移而增加,并且它永远不会减少.

fn modify_name(&'a mut self) {
    self.name = self.name.replacen("az", "", 1).leak();
}

每次你在铁 rust 中看到&,这意味着"这个值是从其他地方的东西借来的."在您的例子中,您希望从一个新字符串借入,但这意味着you need somewhere to put the string that will live at least as long as 101,但是该函数不可能将满足该约束的字符串放在任何地方--除了作为泄漏分配放在堆上.

要做到这一点without泄漏内存,你need改变类型name.

一个可能的解决方案是使用Cow,它代表一个可以被借入or拥有的值. 在本例中,调用test::modify_name后,name字段将为Cow::Owned,无论它以前是borrow 的还是拥有的.

use std::borrow::Cow;

struct test<'a> {
    name: Cow<'a, str>
}

impl<'a> test<'a> {
    fn modify_name(&'a mut self) {
        self.name = self.name.replacen("az", "", 1).into();
    }
}

请注意,即使在拥有name之后,它仍然不能超过本例中的生存期'a.


1好的,还有一种方法,但它要复杂得多,因为它涉及到传入一个引用,引用的是某种比'a更长寿的String存储. 这种类型的内部可能需要unsafe个代码.

Rust相关问答推荐

trait 中self 的显式生命周期似乎导致E0499无法在循环中多次borrow * emits 器作为可变的

有没有办法模仿对象安全克隆?

rust 迹-内存管理-POP所有权-链表

在UdpSocket上使用sendto时的隐式套接字绑定

为什么Rust不支持带关联常量的特征对象?

为什么AsyncRead在Box上的实现有一个Unpin特征绑定?

为什么 `Deref` 没有在 `Cell` 上实现?

为相同特征的特征对象使用 move 方法实现特征

RUST 中的读写器锁定模式

Rust Option 的空显式泛型参数

如何从borrow 的异步代码运行阻塞代码?

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

push 方法是否取得所有权?

如果不满足条件,如何在 Rust 中引发错误

为什么我可以同时传递可变和不可变引用?

如何在 Rust 中编写修改 struct 的函数

如何为枚举中的单个或多个值返回迭代器

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?

为什么这里需要类型注解?

Rust:为什么在 struct 中borrow 引用会borrow 整个 struct?