请教关于返回引用的问题?

看到一段代码大概类似如下这样:

impl ClientBuilder {
    //...

    pub fn gzip(mut self, enable: bool) -> ClientBuilder {
        self.config.accepts.gzip = enable;
        self
    }

    pub fn brotli(mut self, enable: bool) -> ClientBuilder {
        self.config.accepts.brotli = enable;
        self
    }

   //...
}

我的疑问是为什么不是如下代码返回引用,而是返回了一个新的对象? 我理解返回引用不是性能更好吗?

    pub fn gzip(&mut self, enable: bool) -> &mut ClientBuilder {
        self.config.accepts.gzip = enable;
        self
    }

还是我哪里理解有问题?谢谢。

阅读 2k
1 个回答

第一个输入输出都是 move ,并没有带来太多性能问题。(如果 ClientBuilder 实现了 Copy trait,说明 Copy 不会带来性能问题。)

然后考虑使用,第一个可以这样用:

let mut b: ClientBuilder = ...;
b = b.gzip();

但是第二个如果这样用:

let mut b: &mut ClientBuilder = ...;
b = b.gzip();

那就要始终持有一个 &mut borrow 。在 rust 里,持有一个 &mut borrow 意味着不能对它进行 move, & borrow ,也不能再生成其它 &mut borrow ,所以使用起来很不方便。

那如果这样呢:

let mut b: ClientBuilder = ...;
b = *b.gzip(); // !!!!!

你会发现,这里无法赋值,因为有一个 &mut 存在,所以不能 move 。所以只能额外再实现一个 Clone trait ,变成 b = b.gzip().clone(); 。这里反而是一定会拷贝,带来性能问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进