首页 > 解决方案 > From trait 实现可以是有损的吗?

问题描述

语境

我的程序中有一对相关的结构,Rom并且ProfiledRom. 它们都存储一个u8值列表并实现一个共同的特征 ,GetRom以提供对这些值的访问。

trait GetRom {
    fn get(&self, index: usize) -> u8;
}

不同之处在于它只Rom包装了一个简单的Vec<u8>,但ProfiledRom将每个字节包装在一个ProfiledByte类型中,该类型计算它返回的次数get

struct Rom(Vec<u8>);

struct ProfiledRom(Vec<ProfiledByte>);
struct ProfiledByte {
    value: u8;
    get_count: u32;
};

我的大部分程序都对值进行操作,因此我可以根据是否要进行分析来trait GetRom替换Rom或键入/值。ProfiledRom

问题

我已经实现From<Rom> for ProfiledRom了,因为将 a 转换Rom为 aProfiledRom只涉及将每个字节包装在一个新的中ProfiledByte:一个简单且无损的操作。

但是,我不确定是否适合实施From<ProfiledRom> for Rom,因为ProfiledRom包含无法在Rom. 如果您进行了往返转换,这些值将丢失/重置。

From当只使用源对象的一部分时,是否适合实现特征?

有关的

我已经看到标准库没有实现整数转换,From<i64> for i32因为这些可能导致字节被截断/丢失。然而,这似乎与我们这里的情况有些不同。

使用可能截断的整数转换,您需要检查原始数据i64以了解它是否会被正确转换。否则,当您获得越界值时,行为或代码可能会意外更改。然而,在我们上面的例子中,什么数据被保存和什么数据丢失总是静态的清楚。转换的行为不会突然改变。它应该更安全,但它是否适合使用该From特征?

标签: rusttype-conversion

解决方案


From实现通常是无损的,但目前没有严格的要求。

rust-lang/rfcs#2484上正在进行的讨论是相关的。一些可能性包括添加FromLossy特征和更准确地规定From. 我们将不得不看看它的去向。

Target::from(Source)作为考虑,以下是标准库中的一些实现:

无损转换

每个Source值都转换为不同的Target值。

有损转换

多个Source值可以转换为相同的Target值。


推荐阅读