Может ли псевдоним высшего ранга быть связанным ржавчиной? - PullRequest
2 голосов
/ 25 мая 2019

В моей программе есть несколько функций, которые работают с общим целым числом. Они обычно имеют следующую форму:

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,

1 Ответ

1 голос
/ 25 мая 2019

Нет, для этого невозможно использовать новую черту.

Хотя в определение черты можно включить второе требование ...

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: ... границы.Это известная ошибка .

fn function<I: GInteger>(n: &I) -> I
where
    for<'b> &'b I: Mul<Output = I> + Add<Output = I> + Ord,  // meh
{
    n * n
}

Если вы используете ночной Rust, вы можете использовать псевдоним черты (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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...