Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conventions for naming mutable/immutable API functions?

When writing APIs, it's common to have a mutable and an immutable version of a method.

I expected the standard library to have clear conventions about how to name these, but it's not totally consistent1:

What are good naming conventions for the following methods?

pub fn foo****(&self) -> &Bar { ... }
pub fn foo****(&mut self) -> &mut Bar { ... }
  • foo() | foo_mut()

    This seems the most common, and can be seen in Vec.iter and Vec.iter_mut.

  • foo_ref() | foo_mut()

    Used for Any.downcast_ref and Any.downcast_mut.

It seems the first case is more common, so what are the reasons for using the _ref suffix when naming API functions?


1: It is probably consistent and I'm just failing to notice the reasoning.

like image 532
ideasman42 Avatar asked Mar 11 '23 00:03

ideasman42


1 Answers

Yes, conventions for this are defined in RFC 199. The important part is:

The rules

Immutably borrowed by default

If foo uses/produces an immutable borrow by default, use:

  • The _mut suffix (e.g. foo_mut) for the mutably borrowed variant.
  • The _move suffix (e.g. foo_move) for the owned variant.

However, in the case of iterators, the moving variant can also be understood as an into conversion, into_iter, and for x in v.into_iter() reads arguably better than for x in v.iter_move(), so the convention is into_iter.

NOTE: This convention covers only the method names for iterators, not the names of the iterator types. That will be the subject of a follow up RFC.

Owned by default

If foo uses/produces owned data by default, use:

  • The _ref suffix (e.g. foo_ref) for the immutably borrowed variant.
  • The _mut suffix (e.g. foo_mut) for the mutably borrowed variant.

Any::downcast_ref isn't called downcast because there is a method named downcast on Box<Any + 'static> and on Box<Any + 'static + Send> that takes self by value. Naming the method on Any downcast would cause one to shadow the other. So the whole picture is:

  • downcast, takes self, defined on Box<Any + 'static> and Box<Any + 'static + Send>
  • downcast_ref, takes &self, defined on Any + 'static and Any + 'static + Send
  • downcast_mut, takes &mut self, defined on Any + 'static and Any + 'static + Send
like image 54
Francis Gagné Avatar answered Mar 20 '23 01:03

Francis Gagné