何时使用AsRef或其他转换特性为类似字符串的类型

时间:2015-09-14 03:00:24

标签: rust

我在Rust stable中定义了一个crate API(截至目前的版本1.2),并且对于定义我自己的类似字符串的类型的最佳实践感到困惑。

例如,我有一个包裹字符串的Foo类型。

pub struct Foo(String);

我的API隐藏了Foo个实例的构造,而且,因为元组字段是私有的,所以应用程序不能错误地为自己构造无效的Foo值。这意味着我的API会限制应用程序仅使用有效的Foo值。到目前为止一切都很好。

但是,我希望应用程序能够使用Foo实例,就好像它是一个字符串一样 - 打印,记录,将其写入文件,将其传递给第三个 - 接受&str的党包,通过to_string()构建副本并改变副本等等。总之,我希望应用程序能够“抛弃”Foo - 工作和工作引用底层字符串。因为应用程序无法将原始字符串转换回Foo实例,所以保留了类型安全性。

我的问题是:我的crate应该为Foo实现什么转换特性(如果有的话),以允许应用程序“抛弃”Foo - 并使用基础字符串作为原始字符串? Foo转换为&str以避免对基础字符串进行任何不必要的复制非常重要。

例如,怎么样?

impl AsRef<str> for Foo

这是正确的做法吗?是否足以成为惯用语?我应该考虑为Foo实施任何其他转化特征吗?

1 个答案:

答案 0 :(得分:12)

如果Foo 在语义上是字符串,那么实施Deref<Target = str>(或可能是Deref<Target = String>DerefMut)是主要的事情。这将允许&Foo强制转换为&str,因此您可以编写&*foo之类的内容,以便从&str中获取Foo,并foo.starts_with("bar")等等,调用str上定义的方法。

实施AsRef对某些事情也是有益的。 Borrow是您可能希望拥有的另一件事,though there are things to consider before doing so