我怎样才能制作一个可能有也可能没有定义的字段的结构?

Posted

技术标签:

【中文标题】我怎样才能制作一个可能有也可能没有定义的字段的结构?【英文标题】: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 定义一个关联的常量与我想要的很接近,但它需要是可变的。

【问题讨论】:

【参考方案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 的包装器类型,而不是原始(指针?)类型。

以上是关于我怎样才能制作一个可能有也可能没有定义的字段的结构?的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能找到部分单词匹配/找到c ++

我怎样才能找到程序停滞的原因?

当另一个字段数据不存在时清除一个字段

我怎样才能使禁用的字段变灰?

我怎样才能制作这个形状的按钮组?

初始化后如何访问自定义视图属性