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

How can I make a struct which may or may not have a field defined?

我正在研究多项式的实现,它在整数系数的情况下使用 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 定义关联常量接近我想要的,但它需要是可变的。

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

它需要一些小技巧,使用新特征和您要支持的每个 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 = ();
}