rust 有没有办法防止try_from使用可变引用?

xdnvmnnf  于 2023-01-13  发布在  其他
关注(0)|答案(2)|浏览(154)

我有一个结构体

struct Triangle {
    normal: Normal,
    vertices: [Vertex; 3],
}

我想从Read类型反序列化。我认为实现TryFrom是惯用的,因为我将字节流转换为三角形,但它可能会失败。

impl TryFrom<&mut dyn std::io::Read> for Triangle {
  type Error = std::io::Error;
  fn try_from(reader: &mut dyn std::io::Read) -> Result<Self, Self::Error> {
    Ok(Self {
        normal: Normal::try_from(reader)?,
        vertices: [Vertex::try_from(reader)?, Vertex::try_from(reader)?, Vertex::try_from(reader)?]
    })
  }
}

我相信我可以把reader : &mut Read的所有用法都推到Triangle实现中,但是
1.我喜欢在对象自己的impl和
1.当我尝试解析多个三角形来构建网格时,我会遇到同样的问题
我开始感觉到实现TryFrom是错误的方法,但是在我放弃之前,我想我应该问一下是否有一个干净的方法让Normal::try_From借用读取器,然后让Vertex::try_from在遵循所有权规则的同时借用读取器。
以下是该模块的完整列表:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d79881fee912acf0fa4496f90a34df86
(我知道STL在每个三角形后都有一个u16属性,只是还没有开始使用它)

p5cysglq

p5cysglq1#

您可以完全限定该调用,尽管我不清楚为什么它没有首先编译:

impl TryFrom<&mut dyn std::io::Read> for Triangle {
    type Error = std::io::Error;
    fn try_from(reader: &mut dyn std::io::Read) -> Result<Self, Self::Error> {
        Ok(Self {
            normal: <Normal as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
            vertices: [
                <Vertex as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
                <Vertex as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
                Vertex::try_from(reader)?,
            ],
        })
    }
}

但我只实现了一个自定义方法。

svgewumm

svgewumm2#

我可以用一点压力让它工作:

impl TryFrom<&mut dyn std::io::Read> for Triangle {
    type Error = std::io::Error;
    fn try_from(reader: &mut dyn std::io::Read) -> Result<Self, Self::Error> {
        Ok(Self {
            normal: Normal::try_from(reader as &mut _)?,
            vertices: [
                Vertex::try_from(reader as &mut _)?,
                Vertex::try_from(reader as &mut _)?,
                Vertex::try_from(reader as &mut _)?,
            ],
        })
    }
}

我理解 "移动值的使用:reader " 错误可能发生在编译器一般理解上下文,但不考虑重新借用而不是像在其他上下文中那样移动的情况下。请参阅:Do mutable references have move semantics?.
然而,我也感到困惑的是,使用&mut *reader也不起作用,并产生 "不能一次多次借用*reader作为可变的" 错误。编译器没有缩短引用的生命周期,似乎认为重新借用需要持续与原始引用一样长的时间。
幸运的是,上面的语法看起来很管用。

相关问题