返回泛型类型的 Rust 函数

Rust Function Returning a Generic Type

提问人:Hakob Arshakyan 提问时间:11/12/2023 最后编辑:user3840170Hakob Arshakyan 更新时间:11/14/2023 访问量:86

问:

use std::marker::PhantomData;

fn main() {
    pub type KG = u32;

    #[derive(Eq, PartialEq, Debug, Clone, Copy)]
    pub struct Pound(pub u32);

    impl From<Pound> for KG {
        fn from(p: Pound) -> Self {
            p.0 / 45
        } 
    }
    
    impl From<KG> for Pound {
        fn from(k: KG) -> Self {
            Self(k * 45)
        }
    }

    pub trait Matter {
        /// The output unit of the energy density.
        type Output: Into<KG> + From<KG>;
    
        /// The amount of mass contained in a single unit of matter.
        fn density() -> Self::Output;
    }


    pub struct Iron;
    impl Matter for Iron {
        type Output = Pound;
        fn density() -> Self::Output {
            Pound::from(7800)
        }
    }

    pub struct MatterContainer<M: Matter> {
        volume: u32,
        _marker: PhantomData<M>,
    }

    impl<M: Matter> MatterContainer<M> {
        pub fn new(volume: u32) -> Self {
            Self {
                volume,
                _marker: Default::default(),
            }
        }
    }

    pub trait GetWeight<M: Matter> {
        /// Get the weight of Matter in `m`
        /// This method must be provided as it will be the same in all implementations.
        fn get_weight(&self, m: MatterContainer<M>) -> <M as Matter>::Output {
            todo!()
        }
    }
}

我正在尝试编写一个代码,其中get_weight函数通常通过将物质的密度乘以容器的体积来获取物质容器的重量,但是对于不同的物质,密度以不同的单位给出(在这个例子中,铁密度以磅为单位,但对于其他材料,例如它可以是盎司(为了简单起见,这里没有实现给定问题)),返回类型是泛型 Output 类型。如何在不更改get_weight函数签名的情况下实现它? 谢谢

蚀性状

评论

0赞 cafce25 11/12/2023
我建议你只使用给定的边界,特别是.Output: Into<KG> + From<KG>
0赞 Hakob Arshakyan 11/12/2023
@cafce25感谢您的回复,您能否提供一个代码片段?
0赞 Anders Evensen 11/13/2023
您提供的代码存在许多问题,导致其无法按原样编译(例如,将 u32 除以浮点数)。你能修复这些错误吗?
0赞 Hakob Arshakyan 11/13/2023
@AndersEvensen感谢您的回复,您所说的问题现已解决。你能再看一遍代码吗?
1赞 Hakob Arshakyan 11/13/2023
嘿,@FZs您的解决方案略有改进(您还必须更改 density.into(),因为编译器不允许将输出乘以 u32)。关于你的最后一个问题,它可以用更简单的方式简化,它只是一种掌握特征的练习;谢谢;

答:

-3赞 Hakob Arshakyan 11/13/2023 #1
(M::density().into() * m.volume).into()

评论

2赞 Toerktumlare 11/14/2023
请更新您的答案,而不仅仅是代码,包括解释,以便此答案将来可以帮助其他人。