【问题标题】:When to use AsRef or other conversion traits for string-like type何时对类字符串类型使用 AsRef 或其他转换特征
【发布时间】:2015-09-14 03:00:24
【问题描述】:

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

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

pub struct Foo(String);

我的 API 隐藏了 Foo 实例的构造,此外,由于元组字段是私有的,应用程序不会错误地为自己构造一个无效的 Foo 值。这意味着我的 API 将应用程序限制为仅使用有效的 Foo 值。到目前为止一切顺利。

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

我的问题是:如果有的话,我的 crate 应该为 Foo 实现哪些转换特征,以允许应用程序“抛弃”Foo-ness 并将底层字符串作为原始字符串处理?将Foo 转换为&str 非常重要,以避免对底层字符串进行任何不必要的复制。

例如,怎么样?

impl AsRef<str> for Foo

这是正确的做法吗?成语就够了吗?我还应该考虑为Foo 实施其他转换特征吗?

【问题讨论】:

    标签: rust


    【解决方案1】:

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

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

    【讨论】:

    • 您的starts_with 示例清楚了很多。但是,我已经阅读了有关AsRefBorrow 的书籍部分——仍然不清楚。 AsRef 是否允许强制转换为 &amp;str 但不允许 starts_with 示例?在哪些情况下我应该实现AsRef instead of Deref`?我应该同时实现吗?
    • Deref 很神奇,可以为一种类型完成。 AsRef 完全没有魔法,可以为多种类型完成。两者都实现很常见。
    • 我将链接更改为(已弃用)第一版的原因有两个:old desired link 或多或少已死,并且该页面没有进入第二版。但是,您可以添加指向 AsRefBorrow 文档的链接
    猜你喜欢
    • 2021-06-14
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    相关资源
    最近更新 更多