我的程序有许多对通用整数进行运算的函数。它们通常具有以下形式:
use num::{FromPrimitive, Integer, ToPrimitive};
use std::cmp::Ord;
use std::ops::{Add, Mul};
fn function<'a, I>(n: &'a I) -> I
where
I: Integer + Clone + FromPrimitive + ToPrimitive,
for<'b> &'b I: Mul<Output = I> + Add<Output = I> + Ord,
{
}
我想别名通用类型要求:
I: Integer + Clone + FromPrimitive + ToPrimitive,
for<'b> &'b I: Mul<Output = I> + Add<Output = I> + Ord,
这样我就不需要每次都重写它们。最初,我认为宏会有所帮助,但看起来它们在C语言中不起作用,所以我寻找了另一种方法。
我找到了满足第一个要求的方法。必须在任何类型T上对定义的特征应用默认实现。
trait GInteger: Integer + Clone + FromPrimitive + ToPrimitive {}
impl<T: Integer + Clone + FromPrimitive + ToPrimitive> GInteger for T {}
然后我可以简单地写:
I: GInteger
代替
I: Integer + Clone + FromPrimitive + ToPrimitive,
如何别名第二个要求?有可能吗?
for<'b> &'b I: Mul<Output = I> + Add<Output = I> + Ord,
答案 0 :(得分:1)
不,不能为此使用新特征。
虽然可以将第二个要求包括在特征定义中...
trait GInteger: Integer + Clone + FromPrimitive + ToPrimitive
where
for<'b> &'b Self: Mul<Output = Self> + Add<Output = Self> + Ord,
{
}
rustc不会为您详细说明where
子句,因此在function()
的声明中,您仍然需要编写where for<'b> &'b I: ...
绑定。这是known bug。
fn function<I: GInteger>(n: &I) -> I
where
for<'b> &'b I: Mul<Output = I> + Add<Output = I> + Ord, // meh
{
n * n
}
如果您使用每晚的Rust,则可以改用trait alias (RFC 1733),从而完全解决了这个问题。
#![feature(trait_alias)]
use num::{FromPrimitive, Integer, ToPrimitive};
use std::cmp::Ord;
use std::ops::{Add, Mul};
// Define a trait alias
trait GInteger = Integer + Clone + FromPrimitive + ToPrimitive
where
for<'b> &'b Self: Mul<Output = Self> + Add<Output = Self> + Ord;
// Just use it
fn function<I: GInteger>(n: &I) -> I {
n * n
}