Closed Profpatsch closed 5 years ago
I have to apologize for not responding for such a long time (thinks happened ¯_(ツ)_/¯).
vec.into_vec()
is a named version of vec.into()
for cases where just using Into
is ambiguous for either the rust compiler or human reading the code. (I.e. it's a short form of <Vec1<T> as Into<Vec<T>>>::into(vec)
).
Also I think you misunderstand how the naming schema works. It's based on the kind of operation done not the (time/memory) cost this operation causes. It should be more something on the line of:
into_*
=> fn(self) -> T
consumes self
returning a instance of a new type by converting this type into it. It's often costly as converting to a new type might include doing all kind of expensive operations. But might also be cheap or even free if the conversion happens to be simple. This tends to be a alias for some Into<...>
implementation. It isn't if a Into
impl. cannot be done as it needs additional parameters. Or if you want to make this conversion more explicit for some reason.to_*
=> fn(&self) -> T
, fn(&self) -> Result<T,E>
takes a reference to self
returning a new type bases on the value of the current type. Is normally more expensive then a similar into_*
function as it needs to copy values and convert to a new type. A naive implementation might literally implement it as .clone().into()
, but it might be faster then that.as_*
=> fn(&self) -> &T
takes a reference to self
and returns a reference to a different type. This is normally only possible if the type wraps another type. It is often a alias for a AsRef<..>
implementation. E.r. &str
has a as_bytes()
implementations which is a alias for AsRef<[u8]>
. as_*_mut
fn(&mut self) -> &mut T
like as_*
but normally aliases a AsMut
implementation.Note that there are some exceptions:
Copy
types normally implement this functions by having a self
parameter as it tends to be faster.as_
refers to the as
operator not the AsRef
/AsMut
trait.into_*
methods might return a result. Through by now it's better to name them try_into_*
and also implement TryInto
for them.to_*
methods might return a result, too. I think no one uses try_to_*
which might be because there are not To
,TryTo
traits? Or maybe because it looks bad? Is more to type? I don't know but CStr.to_str()
is a good example for this.as_
or into_
method but not implement AsRef
/Into
, most times it's because the author forgot about it or just didn't bother. Through sometimes it intentional if the author doesn't wants the method to be more visible to anyone reading the code.Don't misunderstand:
as_
still should be cheap because it normally is cheap and people would be surprised if it isn't, in a similar way as Deref
should be cheap, but less strictly.Ah, thank you for the in-depth explanation.
I think I saw the table at https://rust-lang-nursery.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv before I had actual knowledge about ownership and reduced it to complexity.
Rust has a convention for naming operations that convert data structures:
as_*
: no overheadinto_*
: varying overhead, mostly small overheadto_*
: overhead (e.g.O(log(n))
orO(n)
)into_vec
just returns the internally wrappedvec
, so incurs no runtime overhead (the compiler uses the same memory representation for both). It should be renamedas_vec
andinto_vec
deprecated.