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

问题描述 投票:13回答:1

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

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

pub struct Foo(String);

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

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

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

例如,怎么样?

impl AsRef<str> for Foo

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

rust
1个回答
12
投票

如果Foo在语义上是一个字符串,那么实现Deref<Target = str>(或可能是Deref<Target = String>DerefMut)是主要的事情。这将允许&Foo强迫&str,所以你可以写像&*foo这样的东西,以获得&strFoofoo.starts_with("bar"),调用str定义的方法。

实施AsRef对某些事情也会有所帮助。 Borrow是你可能想要的另一件事,though there are things to consider before doing so

© www.soinside.com 2019 - 2024. All rights reserved.