[질문]
rust conflicting implementations
익명(112.216)
2020-04-02 15:31
추천 0
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() {}
Standard Error
Compiling playground v0
.0.1 (/playground
)
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 a new
impl of
trait `std
::convert
::From
<&str
>`
for type `i32`
in future versions
error
: aborting due to previous error
For more information about this error
, try `rustc
--explain E0119`
.
error
: could not compile `playground`
.
To learn more
, run the command again with
--verbose
.
str 과 Into 가 로컬크레잇이 아니며 향후 str이 Into 를 구현할 가능성 때문에
이런 에러가 나는게 맞는건가?
근데 이 에러는 좀 너무 빡치게함.. 아니 종일 짠 코드를 죄다 갈아엎을수도 없고
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8876aa5bdfd74f63b1bfc979d474be11
이런걸 허용하면 구현을 추가 했을뿐인데 밑에놈들이 줄줄이 터질수있음
만약 str나 Into가 로컬이면 밑에놈이 터지기전에 로컬부터 터지니 괜찮고
아 혼돈의 도가니네
이렇게 로컬 트레잇 하나 만들어서 타입을 확정지어서 구현하는게 한가지 방법이고 래핑해서 UiId만 구현하는 뉴타입 하나 만들어도됨
둘다 사용처가 조금씩 달라서 같이쓸수도 있고
흠 fundamental attribute 쓰려고 했는데 다시 좀 생각해야겠다
그런거 쓰는거 아님 스마트 포인터들 쓰라고 있는것
아 그리고 저런거 구현할때 타이핑 많아지는거 매크로쓰면 뚝딱임
impl_uiid_with_into_i32!(i32, i16, i8);
즉 외부 crate 에 있는 타입이 실제 구현되어 있지는 않더라도 구현 및 유도될 수 있는 가능성이 있을 경우 conflict 에러가 발생. 때문에 로컬 trait 으로 bound 해주거나 명확한 타입을 나누도록 해야한다.. 이렇게 이해하는게 맞나?
뭐 그렇게 보면 될듯
더 들어가고 싶으면 rust orphan rule 찾아보셈