Как реализовать черту для всех числовых типов (включая ссылки) с помощью одного макроса вместо использования обобщений? - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь реализовать черту для следующих типов: i32, &i32, &mut i32, std::num::NonZeroI32 без использования обобщений.Поэтому я использую макрос, но я не хотел бы дублировать код.

Я не могу найти формулу, которая позволяет преобразовать все эти типы в простое i32.

Моя попытка:

use std::borrow::Borrow;

trait Foo {
    fn foo(self);
}

macro_rules! impl_foo {
    ( $t0:ty as $t:ty ) => {
        impl Foo for $t0 {
            fn foo(self) {
                let _ = <$t>::from(*(self.borrow()));
            }
        }
    }
}

impl_foo!(i32 as i32);
impl_foo!(std::num::NonZeroI32 as i32);
impl_foo!(&'_ i32 as i32);
impl_foo!(&'_ mut i32 as i32);

1 Ответ

1 голос
/ 19 сентября 2019

Вы можете объединить clone и into для поддержки ссылок и простых преобразований вместе.

macro_rules! impl_foo {
    ( $t0:ty as $t:ty ) => {
        impl Foo for $t0 {
            fn foo(self) {
                let _: $t = self.clone().into();
            }
        }
    }
}

Clone::clone будет запретом для значения и покажет базовый тип, еслиэто ссылка.Результат clone() является однозначным, поэтому тип ввода into() также будет однозначно выведен.

Для простых типов Copy следует ожидать, что clone будет реализован как memcpyв большинстве случаев, так что это не должно быть проблемой производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...