【问题标题】:How can I make a struct which may or may not have a field defined?我怎样才能制作一个可能有也可能没有定义的字段的结构?
【发布时间】:2021-10-02 22:20:57
【问题描述】:

我正在研究多项式的实现,它在整数系数的情况下使用 C 库。但是,当系数来自其他环时,我想定义一个不同的实现。当我们将使用 C 库时,我们需要处理一些我们传递给 C 的底层值,这些值分组在一个结构中。否则,不需要定义这些值。我该如何实施?这是我想要的模型:

pub struct Poly<T> {
  coeff_type: T,
  c_value: StructDependingOnT, // only needs to be defined when T is an integer for example
}

我的想法是有一个特征来指定系数类型何时意味着我们将使用 C 库:

pub struct Poly<T> {
  coeff_type: T,
}

pub trait UsesC<T> { // T is the underlying c_value needed above
  fn get_c_value(&self) -> T;
} 

impl UsesC<StructDependingOnT> for Poly<CoefficientType> {
  fn get_c_value(&self) -> StructDependingOnT {
    // ??
  }
}

这里的问题是 c_value 不是结构的字段。有没有办法只在某些时候定义一个字段,比如当它实现某个特征时?为 UsesC 定义一个关联的常量与我想要的很接近,但它需要是可变的。

【问题讨论】:

    标签: struct rust traits


    【解决方案1】:

    您不能使该字段消失,但您可以使用大小为零的类型。

    对于你想要支持的每个 T,使用具有关联类型的新特性需要一些技巧。

    fn main() {
        let p1: Poly<f32> = Poly::default();
        let p2: Poly<i32> = Poly::default();
        println!("p1 = {:?}", p1); // "p1 = Poly { coeff_type: 0.0, c_value: () }"
        println!("p2 = {:?}", p2); // "p2 = Poly { coeff_type: 0, c_value: IntRing }"
    }
    
    use core::fmt::Debug;
    
    pub trait Polyable {
        type Extra: Default + Debug;
    }
    
    #[derive(Default, Debug)]
    pub struct Poly<T: Polyable> {
        coeff_type: T,
        c_value: <T as Polyable>::Extra,
    }
    
    #[derive(Default, Debug)]
    pub struct IntRing {}
    
    impl Polyable for i32 {
        type Extra = IntRing;
    }
    
    impl Polyable for f32 {
        type Extra = ();
    }
    

    【讨论】:

    • 谢谢!这似乎做我想要的。在接受之前,我会稍微介绍一下,以防出现其他解决方案。
    • 我知道这可能最适合作为另一个问题,但我想在这里提一下,以防您有任何想法:因为我使用的是 C 绑定,所以我需要实现 Drop 以正确释放内存.显然,执行“impl Drop for Poly”是无效的(编译器抱怨“Drop impls cannot be specialized”)。那么这种 Poly 构造是否注定要失败?
    • 想必实现drop的需求来自c_value?在这种情况下,我会使用为c_value 类型实现Drop 的包装器类型,而不是原始(指针?)类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多