Let's assume we have struct.
struct User {
name: String,
}
Which impl is preferred?
impl User {
fn new<N: AsRef<str>>(name: &N) -> Self {
User {
name: name.as_ref().to_owned(),
}
}
}
or
impl User {
fn new(name: String) -> Self {
User {
name: name,
}
}
}
I think that second form is more clear to user.
sorear
2
The second form is generally better because:
- it allows you to plug in an existing string on the heap if you have one and don't mind losing ownership of it
- it makes the potentially expensive operation explicit in the caller.
If you have a lot of call sites (tens), then ergonomics becomes a consideration, although it will be a case-by-case thing.
1 Like
If allocations are an issue, you can also consider putting a &str
or a Cow<str>
into the struct.
nielsle
4
The following is a little more complex, but it may lead to a nicer API
impl User {
fn new<T: Into<String>>(name: T) -> Self {
User { name: name.into() }
}
}
See clap for an example of a very nice API
1 Like