как реализовать fmt :: Display на пользовательский тип? - PullRequest
2 голосов
/ 14 июня 2019

У меня есть свой пользовательский тип, и это кусок 32 байта:

pub type Address = [u8; 32];

Поэтому, чтобы отобразить этот тип, у меня есть пользовательский форматер:

impl fmt::Display for Address {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let public_key = sr25519::Public::from_raw(self);
        let address = public_key.to_ss58check();
        write!(f,"{}",address)
    }
}

Но яне могу скомпилировать это:

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
   --> core/linix-primitives/src/lib.rs:122:1
    |
122 | impl fmt::Display for Address {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate

Я понимаю, что для реализации черты мне нужно иметь одно из двух: либо определение type локально, либо определение trait локально.

Ну, я уже определил тип локально:

pub type Address = [u8; 32];

так, почему он жалуется ???

1 Ответ

3 голосов
/ 14 июня 2019

Проблема здесь в том, что следующее не объявляет новый тип:

pub type Address = [u8; 32];

Но вместо этого псевдоним типа, который ближе к typedef в стиле c. Это означает, что ваш код превращается в следующее:

impl fmt::Display for [u8; 32] {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let public_key = sr25519::Public::from_raw(self);
        let address = public_key.to_ss58check();
        write!(f,"{}",address)
    }
}

И здесь [u8; 32] не является локальным типом. Что вы, вероятно, хотите сделать, это использовать так называемый шаблон newtype . Возможно, вы захотите добавить к этому атрибут #[repr], если ваш тип может иметь некоторые отступы.

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