Как я могу реализовать черту От для всех типов, реализующих черту, но использовать определенную реализацию для определенных типов? - PullRequest
0 голосов
/ 15 сентября 2018

Я реализую черту std::convert::From для структуры, содержащей Cow<str>.Есть ли способ использовать одну и ту же реализацию для всех различных типов целых чисел (u8, u16, u32, usize и т. Д.)?

use std::borrow::Cow;

pub struct Luhn<'a> {
    code: Cow<'a, str>,
}

Я могу легко реализовать код для всех целых чисел, используя черту, привязанную к черте ToString, но тогда я не могу использовать конкретную реализацию для str и String - таким образом, преимуществаCow не может быть использован.Когда я пишу конкретные реализации для str и String, я получаю ошибку компиляции:

error[E0119]: conflicting implementations of trait `std::convert::From<&str>` for type `Luhn<'_>`:
  --> src/lib.rs:23:1
   |
7  | impl<'a> From<&'a str> for Luhn<'a> {
   | ----------------------------------- first implementation here
...
23 | impl<'a, T: ToString> From<T> for Luhn<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Luhn<'_>`

Я понимаю, что это связано с тем, что Rust не предлагает функциюперегрузка.Как это можно решить элегантным способом?

impl<'a> From<&'a str> for Luhn<'a> {
    fn from(input: &'a str) -> Self {
        Luhn {
            code: Cow::Borrowed(input),
        }
    }
}

impl<'a> From<String> for Luhn<'a> {
    fn from(input: String) -> Self {
        Luhn {
            code: Cow::Owned(input),
        }
    }
}

impl<'a, T: ToString> From<T> for Luhn<'a> {
    fn from(input: T) -> Self {
        Luhn {
            code: Cow::Owned(input.to_string()),
        }
    }
}

1 Ответ

0 голосов
/ 15 сентября 2018

Поскольку &str и String оба реализуют ToString, вы можете использовать нестабильную специализацию :

#![feature(specialization)]

use std::borrow::Cow;

pub struct Luhn<'a> {
    code: Cow<'a, str>,
}

impl<'a, T: ToString> From<T> for Luhn<'a> {
    default fn from(input: T) -> Self {
//  ^^^^^^^
        Luhn {
            code: Cow::Owned(input.to_string()),
        }
    }
}

impl<'a> From<&'a str> for Luhn<'a> {
    fn from(input: &'a str) -> Self {
        Luhn {
            code: Cow::Borrowed(input),
        }
    }
}

impl<'a> From<String> for Luhn<'a> {
    fn from(input: String) -> Self {
        Luhn {
            code: Cow::Owned(input),
        }
    }
}

При этом,вы не можете реализовать Display для Luhn, потому что вы столкнетесь с Как существует конфликтующая реализация `From` при использовании универсального типа?

...