There are several important naming conventions that still need to be formally settled:
- prefix
mut_
versus suffix_mut
(https://github.com/rust-lang/rust/issues/13660) -
mut
versusmut_ref
(https://github.com/rust-lang/rust/pull/14299) -
unwrap
,get
,get_ref
, andtake
conventions (https://github.com/rust-lang/rust/issues/13159, https://github.com/rust-lang/rust/issues/9784) - iterator functions
- conversion functions/methods (https://github.com/rust-lang/rust/issues/7087)
This post tries to resolve them together.
Prefix versus suffix for mut
qualifier
https://github.com/rust-lang/rust/issues/13660
Currently the libraries are not terribly consistent about how to signal mut
variants of functions; sometimes it is by a mut_
prefix, sometimes a _mut
suffix, and occasionally with _mut_
appearing in the middle. While there are
arguments in favor of each of the positions, we stand to gain a lot by
standardizing, and to some degree we just need to make a choice.
The proposed rule is simple: prefer a _mut
suffix, except when part of a type
name (as in as_mut_slice
), where the word mut
should appear as it would
appear in the type.
Rationale: using a suffix makes it easier to visually group non-mut
and
mut
variants together (including when sorted alphabetically). It puts the
emphasis on the functionality, rather than the mut
qualifier.
mut
versus mut_ref
https://github.com/rust-lang/rust/pull/14299
Some places in the library, we say things like as_ref
and as_mut
, and others
we say get_ref
and get_mut_ref
.
In general, when types are written as part of a function name, we often
abbreviate those types (e.g. iter
).
Proposal: standardize on mut
as being the abbreviation for a mutable
reference, rather than mut_ref
.
Rationale: it’s shorter, and pairs like as_ref
and as_mut
have a pleasant
harmony that doesn’t place emphasis on one kind of reference over the other.
Accessing containers/wrappers/cells
https://github.com/rust-lang/rust/issues/13159, https://github.com/rust-lang/rust/issues/9784
Data structures that contain elements, wrap other data structures, or provide interior mutability all need to provide ways to access their internals. These methods often have variants to access the data by value, by reference, and by mutable reference. Right now, there are a variety of names used for this functionality, in some cases provided as fallible operations, in other cases not.
Containers
For a container with keys/indexes of type K
and elements of type V
, the proposal is:
// Infallbile element lookup:
fn get(&self, key: &K) -> Option<&V>
fn get_mut(&mut self, key: &K) -> Option<&mut V>
// Convenience for .get(key).map(|elt| elt.clone())
fn get_clone(&self, key: &K) -> Option<V>
// Fallible element lookup:
impl Index<K,V> for ...
impl IndexMut<K,V> for ...
The name find
would be deprecated in favor of get
under this proposal.
Wrappers/Cells
Prefer specific conversion functions like as_bytes
or into_vec
whenever
possible. Otherwise, use:
// Infallible extraction
fn get(&self) -> &V
fn get_mut(&mut self) -> &mut V
fn unwrap(self) -> V
Wrappers/Cells around Copy
data
// Infallible extraction
fn get(&self) -> V
Option
and Result
Finally, we have the cases of the Option
and Result
type, which play a special role around fallibility.
For Option<V>
:
// Fallible extraction
fn assert(self) -> V
fn expect(self, &str) -> V
and drop the get_ref
and get_mut_ref
methods in favor of as_ref().assert()
and as_mut().assert()
.
For Result<V, E>
:
// Fallible extraction
fn assert(self) -> V
fn assert_err(self) -> E
The methods like unwrap_or
and unwrap_or_else
keep their current names.
Rationale: taking all of the above proposals, fallibility is pushed into two
clearly marked places: indexing and assert
.
Iterator functions
The current iterator conventions are:
fn iter(&self) -> T // where T implements Iterator<&U>
fn mut_iter(&mut self) -> T // where T implements Iterator<&mut U>
fn move_iter(self) -> T // where T implements Iterator<U>
The move
name is a holdover from an older Rust, and the mut_
prefix is at
odds with the proposal above. Therefore, the new proposed names are:
fn iter(&self) -> T // where T implements Iterator<&U>
fn iter_mut(&mut self) -> T // where T implements Iterator<&mut U>
fn into_iter(self) -> T // where T implements Iterator<U>
Conversion functions
https://github.com/rust-lang/rust/issues/7087
The proposal is just to accept the RFC on conversions found at http://aturon.github.io/style/naming.html, which represents the status quo – which is working quite well.