将通用类型限制为原始数字类型

3

我们可以通过where从句将类型限制为一个或多个特性。

我的问题是:

  • 能否将类型限制为仅原始数字类型?

  • 如何实现?


你想限制接受所有原始数据类型还是特定的一个? - Ömer Erden
@ÖmerErden 如果可以像这样为特质做到这一点,那将是很好的。或者有没有仅限于原始数字的特质可以使用? - Galaxy
顺便说一句。我发现num_traits非常有用。 - Galaxy
是的,你的问题有点宽泛,所以我写了一些表面的解决方案。 - Ömer Erden
3个回答

2

不需要。

要使用参数化类型,您需要让trait定义您想调用的有效操作。 因此,您需要具有所有要调用的操作的一个或多个trait。

Rust中的“原始”类型并没有任何特殊之处。它们通过std::ops的traits来定义它们的运算符(尽管显然使用编译器内部函数),就像任何“非原始”的数字类型一样。

实际上,“原始”和“非原始”数字类型之间的边界甚至有些模糊,因为对于缺乏FPU的目标,标准库可能会在代码中实现浮点类型,并且在Rust中,它可以对用户进行透明处理。

因此,实际上不存在基本数字类型。提供您需要调用的任何运算符来定义数字类型。因此,只需通过std::ops traits限制您的类型即可。

最初的回答。


2
由于原始类型不是特征类型,因此您无法将其用作边界来限制泛型类型。但是,您可以直接为特定类型实现:
struct Struct<T>(T);

trait Printer {
    fn print(&self);
}

impl Printer for Struct<i32> {
    fn print(&self) {
        println!("Printing for i32 value: {}", self.0);
    }
}

fn main() {
    let x = Struct(15_i32);
    let _z = Struct(14.2_f64);

    x.print();
    //_z.print();//compile error
}

游乐场

另外,您可以使用 Borrow<S> 特质作为技巧,您可以将泛型参数限制如下:(T: Borrow<S> 表示 T 可以被借用为 S)。

impl<T> Printer for Struct<T>
where
    T: Borrow<f64> + Debug,
{
    fn print(&self) {
        println!("Printing for f64 value: {:?}", self.0);
    }
}

游乐场

但是,由于您可以为任何类型实现Borrow<f64>,因此这种限制可能不被视为严格。

此外,仅对于数字原语,您可以使用num-traits crate中的特征,例如ToPrimitiveAsPrimitive


1
如果将特征看作是“编译时鸭子类型”,那么更好的问题是:在一个“数字”中,你正在寻找哪些确切的特征?它们的大多数操作可以定义为对类型的特征约束,请参见:标准操作特征
即使您在外部板条箱中定义了特征,并仅针对特定类型在该外部板条箱中实现了行为,也认为特征实现规则将有所帮助(即,如果特征或类型或两者都在当前板条箱中,则只能将特征实现为类型),但仍然不会限制任何人为其自己的类型实现特征。
因此,我认为除了为每种原始数字类型实现不带泛型的行为外,没有其他选择。为避免代码重复,我可能会使用宏——毕竟,从某些方面来看,您手动执行编译器在单态化通用代码时所做的工作。
话虽如此,我认为没有理由将行为限制为数字而不是某些特征,并且我会像第一段描述的那样依赖于它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接