Skip to content

Commit e17bacf

Browse files
committed
Explain difference between from_ constructor and From impl
1 parent c10b4e5 commit e17bacf

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/predictability.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,23 @@ options though, consider the builder pattern ([C-BUILDER]) instead.
194194
Some constructors are "conversion constructors", methods that create a new type
195195
from an existing value of a different type. These typically have names begining
196196
with `from_` as in [`std::io::Error::from_raw_os_error`]. Note also though the
197-
`From` trait ([C-CONV-TRAITS]), which is quite similar. Guidelines for writing a
198-
`From` implementation vs. writing `from_foo` need further examination.
197+
`From` trait ([C-CONV-TRAITS]), which is quite similar. There are three
198+
distinctions between a `from_`-prefixed conversion constructor and a `From<T>`
199+
impl.
200+
201+
- A `from_` constructor can be unsafe; a `From` impl cannot. One example of this
202+
is [`Box::from_raw`].
203+
- A `from_` constructor can accept additional arguments to disambiguate the
204+
meaning of the source data, as in [`u64::from_str_radix`].
205+
- A `From` impl is only appropriate when the source data type is sufficient to
206+
determine the encoding of the output data type. When the input is just a bag
207+
of bits like in [`u64::from_be`] or [`String::from_utf8`], the conversion
208+
constructor name is able to identify their meaning.
209+
210+
[`Box::from_raw`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw
211+
[`u64::from_str_radix`]: https://doc.rust-lang.org/std/primitive.u64.html#method.from_str_radix
212+
[`u64::from_be`]: https://doc.rust-lang.org/std/primitive.u64.html#method.from_be
213+
[`String::from_utf8`]: https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8
199214

200215
Note that it is common and expected for types to implement both `Default` and a
201216
`new` constructor. For types that have both, they should have the same behavior.

0 commit comments

Comments
 (0)