Страницы

Поиск по вопросам

пятница, 7 июня 2019 г.

Rust: преобразование обобщённого типа в конкретный

Собственно код:
extern crate num_traits;
pub trait DigitCount { fn decimal_digit_count(&self) -> usize; }
impl > DigitCount for T { fn decimal_digit_count (&self) -> usize { if self.is_zero() { 1 } else { self.into().abs().log10().trunc() as usize + 1 } } }
Метод decimal_digit_count должен вызываться для любого целого значения и возвращать количество десятичных разрядов в нём:
println!("{}", 123u64.decimal_digit_count());
Вопрос: как правильно записать преобразование T → f64 для последующего вызова методов abs, log10, trunc? В текущем виде компилятор требует аннотацию типа для into(), но если её подставить (into::()), то говорит, что ожидается 0 параметров типов.


Ответ

У самого метода и правда нет типового параметра, потому что он есть у типажа:
pub trait Into { fn into(self) -> T; }
Первый вариант исправления - просто явно указать через промежуточную переменную какой тип мы в итоге хотим получить:
let f: f64 = self.into(); f.abs().log10().trunc() as usize + 1
(playpen)
Второй вариант - использовать UFCS форму вызова метода с явным обозначением T у типажа:
Into::::into(self).abs().log10().trunc() as usize + 1
(playpen)
Метод decimal_digit_count должен вызываться для любого целого значения и возвращать количество десятичных разрядов в нём
На всякий случай еще добавлю что преобразование в f64 реализовано не для всех целых типов. Такое преобразование обязано всегда заканчиваться успехом, что невозможно, например, для u64 или i128 из-за невозможности вместить весь диапазон значений.

Комментариев нет:

Отправить комментарий