Rust 不能像易变的那样借用,因为它位于`&;``后面参考

Rust 不能像易变的那样借用,因为它位于`&;``后面参考,rust,Rust,为了更好地了解Rust,我正在构建一个简单的文本编辑器,并具有以下结构: struct文件{ 行:Vec, 文件名:选项 } impl文件{ fn行(&self,索引:u16)->行(&W){ &self.rows[按usize索引] } } 结构行{ 弦:弦, } 结构编辑器状态{ 档案:档案, } 如您所见,我将编辑器的状态保留在一个结构中,该结构引用文件,该文件包含许多行,其中包含一个字符串(每个结构都有更多字段,但我已删除了与问题无关的字段) 现在我想使我的行可编辑并添加以下内容: i

为了更好地了解Rust,我正在构建一个简单的文本编辑器,并具有以下结构:

struct文件{
行:Vec,
文件名:选项
}
impl文件{
fn行(&self,索引:u16)->行(&W){
&self.rows[按usize索引]
}
}
结构行{
弦:弦,
}
结构编辑器状态{
档案:档案,
}
如您所见,我将编辑器的状态保留在一个结构中,该结构引用文件,该文件包含许多行,其中包含一个字符串(每个结构都有更多字段,但我已删除了与问题无关的字段)

现在我想使我的行可编辑并添加以下内容:

impl行{
fn插入(&mut self,at:u16,c:char){
设at=at为usize;
如果at>=self.string.len(){
自串推(c);
}否则{
self.string.insert(at,c)
}
}
}
以下是我尝试更新行的方式:

//在实际函数中,我捕获按键,
//从状态中获取正确的行并传递它和按下的
//char到row.insert
fn更新行(mut状态:&mut编辑器状态){
让row=&state.file.row(0);
第行。插入(0,'a');
}
这无法编译:

error[E0596]: cannot borrow `*row` as mutable, as it is behind a `&` reference

从错误中,我可以看出问题在于行应该是可变的,这样我就可以编辑它(这很有意义,因为我正在改变它的字符串)。我不知道a)如何在这里变异字符串,b)如何在不让
始终返回可变引用的情况下执行此操作,就像在所有其他情况下一样,我调用
来读取行,而不是写入行。

您想要的是不可能的。您必须编写两个函数(注意,我将
u16
替换为
usize
——没有理由将每行字符数限制为65536个):

fn行(&self,索引:usize)->&row{
&self.rows[索引]
}
fn行\多行(&mut self,索引:usize)->&mut行{
&多个self.rows[索引]
}

请注意,这是所有防锈代码中的常见模式。例如
Vec
具有
get(idx)
get_mut(idx)

下面是一个更惯用的
文件实现:

impl File {
    fn row(&self, index: usize) -> Option<&Row> {
        self.rows.get(index)
    }

    fn row_mut(&mut self, index: usize) -> Option<&mut Row> {
        self.rows.get_mut(index)
    }
}
impl文件{
fn行(&self,索引:usize)->选项{
self.rows.get(索引)
}
fn row_mut(&mut self,索引:usize)->选项{
self.rows.get_mut(索引)
}
}
注意事项如下:

  • 如果
    索引
    超出范围,您的实现就会死机。处理这个问题的惯用方法是返回一个选项,
    get
    get_mut
    允许您免费获取
  • 使用u16没有多大意义,因为Vec是使用usize编制索引的。在这里使用
    u16
    是任意的,除非您确实想提供硬编码限制。在这种情况下,我将不依赖于类型的max值,而是一个常数,这将使意图更加清晰

@SvenMarnach这会给你一个
&mut&Row
,这并没有真正的帮助。不,点击那个。
row()
函数只返回只读引用,因此不能使用该引用修改该行。您需要添加一个
行_mut()
,返回一个可变引用。感谢您a)回答问题,b)将我指向
get
get_mut
,以及c)突出显示
u16
问题,这真的没有多大意义。