Generi c цифра c функция с использованием черт и `match` - PullRequest
0 голосов
/ 02 февраля 2020

Я пытаюсь создать обобщенную c функцию форматирования, которая принимает два целых числа T в качестве знаменателя и знаменателя и форматирует дробь в соответствии с некоторыми простыми правилами.

Я посмотрел на num черты, однако, все еще не могут заставить его работать. У меня уже более подробный код, чем я хотел, поэтому я подумал, что пришло время обратиться за помощью.

extern crate num;
use num::{Integer,FromPrimitive};

fn format_rational<T>(n: T, d: T) -> String
    where T: Integer + FromPrimitive + fmt::Display
{
    let one: T = FromPrimitive::from_u16(1).unwrap();
    let ten: T = FromPrimitive::from_u16(10).unwrap();
    let hun: T = FromPrimitive::from_u16(100).unwrap();
    let tho: T = FromPrimitive::from_u16(1000).unwrap();

    let precision = match d {
        one => Some(1),
        hun => Some(2),
        tho => Some(3),
        _ => None,
    };

    match precision {
        Some(p) => format!("{:.*}", p, n as f32 / d as f32),
        None => format!("{} / {}", n, d),
    }
}

Это ошибки с

non-primitive cast: `T` as `f32`

Но когда я изменяю первый format! строка к

Some(p) => format!("{:.*}", p, f32::from(n) / f32::from(d))

Я получаю эту ошибку:

the trait bound `f32: std::convert::From<T>` is not satisfied

, которую я интерпретирую как «От не существует для типа f32», что имеет смысл. Как возможно f32 здесь, когда признак Num, что подразумевает Eq, что подразумевает, что оно должно исключать поплавки? (так как поплавки реализуют только PartialEq). Наконец, есть ли способ просто работать с From<T>?

Чего мне не хватает? Или проблема может быть решена другим (более простым) способом? Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 февраля 2020

Избегать некоторых unwrap с, по сравнению с вашим ответом:

extern crate num;
use std::fmt;
use num::{ToPrimitive};

pub fn format_rational<T>(n: T, d: T) -> String
    where
        T: ToPrimitive + std::ops::Div + fmt::Display,
        <T as std::ops::Div>::Output: fmt::Display,
{
    let precision = match d.to_usize() {
        Some(1) | Some(10) => Some(1),
        Some(100) => Some(2),
        Some(1000) => Some(3),
        _ => None,
    };

    match precision {
        Some(p) => format!("{:.*}", p, n.div(d)),
        None => format!("{} / {}", n, d),
    }
}
0 голосов
/ 02 февраля 2020

Я решил это сегодня. Есть ли лучшие способы сделать это?

extern crate num;
use std::fmt;
use num::{ToPrimitive};

pub fn format_rational<T>(n: T, d: T) -> String
    where T: ToPrimitive + fmt::Display
{
    let precision = match d.to_usize().unwrap() {
        1 | 10 => Some(1),
        100 => Some(2),
        1000 => Some(3),
        _ => None,
    };

    match precision {
        Some(p) => format!("{:.*}", p, ToPrimitive::to_f32(&n).unwrap() / ToPrimitive::to_f32(&d).unwrap()),
        None => format!("{} / {}", n, d),
    }
}
...