rust 是否可以使用一个std::convert::From实现将类型A转换为B以及将B转换为A?

afdcj2ne  于 2022-12-29  发布在  其他
关注(0)|答案(2)|浏览(149)

问题

我想编写一个函数,它允许我将类型A(在本例中为u8)转换为类型B(一个自定义类型),然后再从类型B转换回类型A。根据entry about the traits From and Into of Rust by Example的第一段:
FromInto特性是内在联系的,这实际上是它实现的一部分。如果你能够将类型A从类型B转换过来,那么你应该很容易相信我们应该能够将类型B转换成类型A。
然而,实现From(即impl From<A> for B)允许我从A转换到B,并且 * 只能 * A转换到B,除了两种不同的方式(仍然不确定为什么需要两种方式,但无论如何)。我可以使用相同的实现从B转换到A吗?或者没有办法使用已经存在的信息吗?

我所尝试的

我尝试在NormalMneumonic类型上实现From(在本例中为TryFrom),如下所示

impl TryFrom<&str> for NormalMneumonic {
    type Error = Error;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "JP" => Ok(Self::Jump),
            // --snip--
            _ => Err("Input is not a normal menumonic."),
        }
    }
}

有了它我就能

let mneumonic_1 /*: Result<NormalMneumonic, _>*/ = NormalMneumonic::try_from("JP");
let mneumonic_2: Result<NormalMneumonic, _> = "JP".try_into();
assert_eq!(mneumonic_1, mneumonic_2);

但是我还没有找到一种方法来将NormalMneumonic转换回&str

let mneumonic_string = NormalMneumonic::Jump.try_into(); // or perhaps &str::try_from(NormalMneumonic::Jump)

一些背景

我正在尝试用Rust为一个简化的汇编语言编写一个汇编器和一个链接器,我定义了一个数据类型来帮助实现这一点,它只是一个枚举,每个有效的枚举都有一个变量。
在编写汇编程序时,我需要读取一些文本文件并写入一些二进制文件,在链接时,我需要读回一些二进制文件并写入另一个二进制文件,考虑到这一点,我一直在寻找一种方法,在字符串切片(&str)或字节(u8)与NormalMneumonic变体之间来回转换。
从我提到的引文中,我认为在类型之间来回转换是From特性的用例,但似乎这本书在这种情况下只是使用了误导性的语言。

ojsjcaue

ojsjcaue1#

不,From<A> for B实现不会创建From<B> for A实现。
From trait只由一个方法fn from(a: A) -> B组成。仅用这个签名,您就能创建所有AB的反向实现吗?当然不能!而且编译器不会查看现有实现的主体来尝试推导其他实现。首先,许多转换是有损耗的,许多转换是容易出错的,并且可能在转换一个方向时遇到障碍,而在转换相反的方向时却不存在。因此,即使编译器查看了现有的实现,它也是不实际的,甚至一般来说是不可能的。
从我提到的引文中,我认为在类型之间来回转换是From特性的用例,但似乎这本书在这种情况下只是使用了误导性的语言。
事实上,你误解了这句话,它实际上是在不同的语境下把同样的话重复了两遍:* “convert type A from type B”* 与 “convert type B to type A” 是相同的操作,都是B -> A,只是短语的主语改变了。这反映了FromInto之间的唯一区别。语法A::from(b)b.into()(带有推断的A)不能用单个trait完成。
如果您希望在处理枚举时更轻松一些,如前所述,strum crate提供了许多派生宏,用于:

有关其他选项,请参阅这些现有答案:

mnemlml8

mnemlml82#

也许strum_macros能帮上忙。
它可以生成将枚举值转换为&str的代码

use strum_macros::IntoStaticStr;

#[derive(IntoStaticStr)]
enum NormalMneumonic {
}

相关问题