Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use as_* vs to_* vs into_* in Rust?

My understanding, based on the standard library examples, is that:

into_ convention is used when the function completely absorbs the ownership and spits out another type, as in into_iter() . Is the understanding correct?

The real confusion is between as_ and to_ .
It seems to_ as in to_owned() takes the reference of a type and spits a new related type (like a type coercion), where as to_string() takes the reference of type and spits a new type (as in type conversion).

But as_ as in as_ptr also seems like type coercion. I couldn't find any examples for this beyond as_ptr or as_mut.

Can someone explain exactly the cases where we need to use the specific naming convention and with a real life example that is beyond what's used in standard library?

like image 512
manikawnth Avatar asked Sep 12 '25 05:09

manikawnth


1 Answers

There is a Naming section of the Rust API Guidelines that includes recommendations for "conversion" methods and shows a handy table:

Prefix Cost Ownership
as_ Free borrowed -> borrowed
to_ Expensive borrowed -> borrowed
borrowed -> owned (non-Copy types)
owned -> owned (Copy types)
into_ Variable owned -> owned (non-Copy types)

The guidelines continue with examples like str::as_bytes(), str::to_lowercase(), String::into_bytes(), etc. and some other considerations for abstraction and mutability.

A quicker way to think about it:

  • if it consumes the data, use into_*
  • if it returns another "view" of the data, use as_*
  • otherwise use to_*

These rules are pretty much followed by the standard library and most ecosystem crates. As always though, these are more guidelines than actual rules. Conventions are helpful but don't need to have strict adherence.

like image 87
kmdreko Avatar answered Sep 14 '25 21:09

kmdreko