/ / Implementaciones conflictivas de rasgos en Rust - genéricos, rust, implementación, rasgos

Implementaciones conflictivas de rasgos en Rust - genéricos, rust, implementación, rasgos

Quiero implementar un rasgo personalizado para &"a str y para números enteros hasta i32, pero Rust no me permite:

use std::convert::Into;

pub trait UiId {
fn push(&self);
}

impl<"a> UiId for &"a str {
fn push(&self) {}
}

impl<T: Into<i32>> UiId for T {
fn push(&self) {}
}

fn main() {}

Esto no se compila con el siguiente error:

error[E0119]: conflicting implementations of trait `UiId` for type `&str`:
--> src/main.rs:11:1
|
7  | impl<"a> UiId for &"a str {
| ------------------------- first implementation here
...
11 | impl<T: Into<i32>> UiId for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&str`
|
= note: upstream crates may add new impl of trait `std::convert::From<&str>` for type `i32` in future versions

&"a str no implementa Into<i32>. ¿Es posible implementar? UiId para &"a str y todo lo que se puede convertir en i32 ¿Sin especificar tipos concretos? ¿Cómo puedo hacer eso?

Respuestas

10 por respuesta № 1

El hecho de que &"a str no implementa Into<i32> no se tiene en cuenta, ya que no hay garantía de que no se pueda agregar más tarde. Esto rompería su código.

Por lo tanto, si se permitiera esto, la posible ruptura dificultaría la adición de implementaciones a los rasgos de la biblioteca.

Desafortunadamente no pude encontrar documentación para eso, ni en El lenguaje de programación Rust Libro ni en el Manual de referencia.

Lo mejor que pude encontrar es RFC 1023, que dice eso una caja [...] no puede confiar en que Type: !Trait sostiene a menos que Type o Trait es local