Skip to content

Commit c7a5907

Browse files
committed
Add more nuance to C-CTOR. Fixes #108
1 parent 48fb831 commit c7a5907

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

README.md

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,11 @@ subtle ways, failure during dereferencing can be extremely confusing.
12871287
<a id="c-ctor"></a>
12881288
### Constructors are static, inherent methods (C-CTOR)
12891289

1290-
In Rust, "constructors" are just a convention:
1290+
In Rust, "constructors" are just a convention. There are a variety of
1291+
conventions around constructor naming, and the distinctions are often
1292+
subtle.
1293+
1294+
A constructor in it's most basic form is an empty `new` method:
12911295

12921296
```rust
12931297
impl<T> Example<T> {
@@ -1306,9 +1310,6 @@ use example::Example;
13061310
let ex = Example::new();
13071311
```
13081312

1309-
This convention also applied to conversion constructors (prefix `from` rather
1310-
than `new`).
1311-
13121313
Constructors for structs with sensible defaults allow clients to concisely
13131314
override using the [struct update syntax].
13141315

@@ -1335,21 +1336,56 @@ impl Config {
13351336
let config = Config { color: Red, .. Config::new() };
13361337
```
13371338

1338-
##### Examples from the standard library
1339-
1340-
- [`std::io::Error::new`] is the commonly used constructor for an IO error.
1341-
- [`std::io::Error::from_raw_os_error`] is a constructor based on an error code
1342-
received from the operating system.
1343-
1344-
[`std::io::Error::new`]: https://doc.rust-lang.org/std/io/struct.Error.html#method.new
1345-
[`std::io::Error::from_raw_os_error`]: https://doc.rust-lang.org/std/io/struct.Error.html#method.from_raw_os_error
1339+
The method `new` should generally be used for the primary method of
1340+
instantiating a type. Sometimes it takes no arguments, as in the
1341+
examples above, sometimes not, is in the constructor for the container
1342+
type `Box`, [`Box::new`], that takes as a single argument the value it
1343+
contains.
1344+
1345+
Some types' constructors, most notably I/O resource types, use
1346+
distinct naming conventions for their constructors, as in
1347+
[`File::open`], [`Mmap::open`], [`TcpStream::connect`], and
1348+
[`UpdSocket::bind`]. In these cases names are chosen as appropriate
1349+
for the domain.
1350+
1351+
Often there are multiple ways to construct a type. It's common in
1352+
these cases for secondary constructors to be be suffixed, `_with_foo`,
1353+
as in [`Mmap::open_with_offset`]. If your type has a multiplicity of
1354+
construction options though, consider the [builder
1355+
pattern][C-BUILDER] instead.
1356+
1357+
Some constructors are "conversion constructors", methods that create a
1358+
new type from an existing value of a different type. These typically
1359+
have names begining with `from_` as in
1360+
[`std::io::Error::from_raw_os_error`]. Note also though the `From`
1361+
trait ([C-CONV-TRAITS]), which is quite similar. Guidelines for
1362+
writing a `From` implementation vs. writing `from_foo` need further
1363+
examination.
13461364

13471365
Note that it is common and expected for types to implement both
13481366
`Default` and an empty `new` constructor. `new` is the constructor
13491367
convention in Rust, and users expect it to exist, so if it is
13501368
reasonable for the basic constructor to take no arguments, then it
13511369
should, even if it is functionally identical to `default`.
13521370

1371+
##### Examples from the standard library
1372+
1373+
- [`std::io::Error::new`] is the commonly used constructor for an IO error.
1374+
- [`std::io::Error::from_raw_os_error`] is a conversion constructor
1375+
based on an error code received from the operating system.
1376+
- [`Box::new`] creates a new container type, taking a single argument.
1377+
- [`File::open`] opens a file resource.
1378+
- [`Mmap::open_with_offset`] opens a memory-mapped file, with additional options.
1379+
1380+
[`File::open`]: https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.open
1381+
[`Mmap::open`]: https://docs.rs/memmap/0.5.2/memmap/struct.Mmap.html#method.open
1382+
[`Mmap::open_with_offset`]: https://docs.rs/memmap/0.5.2/memmap/struct.Mmap.html#method.open_with_offset
1383+
[`TcpStream::connect`]: https://doc.rust-lang.org/stable/std/net/struct.TcpStream.html#method.connect
1384+
[`UpdSocket::bind`]: https://doc.rust-lang.org/stable/std/net/struct.UdpSocket.html#method.bind
1385+
[`std::io::Error::new`]: https://doc.rust-lang.org/std/io/struct.Error.html#method.new
1386+
[`std::io::Error::from_raw_os_error`]: https://doc.rust-lang.org/std/io/struct.Error.html#method.from_raw_os_error
1387+
[`Box::new`]: https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new
1388+
13531389
<a id="flexibility"></a>
13541390
## Flexibility
13551391

0 commit comments

Comments
 (0)