【问题标题】:What is the difference between the FromStr and TryFrom<String> traits?FromStr 和 TryFrom<String> 特征有什么区别?
【发布时间】:2021-05-04 13:38:20
【问题描述】:

在 Rust 中使用 Serde crate 时,我尝试将 #[serde(try_from = String)] container attribute 添加到实现 FromStr 的类型中,因此可以从字符串中解析。不幸的是,这对于 Serde 来说似乎还不够,从编译器错误消息中可以明显看出我也必须手动实现 TryFrom&lt;String&gt;

为什么没有为实现FromStr 的所有类型自动实现TryFrom&lt;String&gt;?为什么字符串的易错转换有一个单独的特征?这两个特征有什么区别?

【问题讨论】:

  • 我认为答案是“出于历史原因”的平均值:AFAIK FromStr 更老,TryFrom 是后来才添加的。但是,您期望的 trait 自动实现听起来很合乎逻辑,也许有技术原因,这并不容易。
  • 您可能会发现serde_with 允许您使用automatically (de)serialize using FromStr and Display 并具有许多其他便利功能很有用
  • 感谢serde_with 的链接。我会看一下,但是由于我的项目以 WASM 为目标,因此我对其他依赖项相当敏感,以防它们增加输出大小。

标签: string rust type-conversion


【解决方案1】:

FromStr 在 Rust 1.0 中稳定,TryFrom 在 Rust 1.34 中稳定;在它存在之前很难使用它。

为什么没有为实现FromStr的所有类型自动实现TryFrom&lt;String&gt;

这会导致已经实现TryFromFromStr 的类型产生歧义。需要一种高级形式的专业化来实现这一点。

为什么字符串的易错转换有一个单独的特征?

FromStr 从借用的字符串切片 (&amp;str) 创建一个拥有值,因此它在语义上与获取 String 的所有权不同。 TryFrom&lt;String&gt; 将允许您重用分配给 String 的内存。

更接近的类比是impl&lt;'a&gt; TryFrom&lt;&amp;'a str&gt; for ...,但是在特征中具有生命周期使得在从字符串中解析值的“简单”情况下使用它变得更加复杂。

另见:

【讨论】:

  • 我应该注意到这两个特征有不同的生命周期要求。不过,实现TryFrom&lt;&amp;str&gt; 和使用#[serde(try_from = "&amp;str")] 似乎工作正常。
【解决方案2】:

TryFrom 是一个通用特征,可以为“任何”类型实现。来自文档:

简单而安全的类型转换,在某些情况下可能会以受控方式失败。

Type -&gt; Type

它还提供了TryInto 的自动实现。

FromStr 主要用于解析类型,也根据文档:

FromStr 的 from_str 方法经常被隐式使用,通过 str 的 parse 方法。

str -&gt; Type

实现它以供str::parse使用

【讨论】:

    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2017-01-01
    • 2017-04-15
    • 2016-11-09
    • 2016-03-26
    • 1970-01-01
    相关资源
    最近更新 更多