Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

rust - Making a generic From/Into shortcut for two-steps From

StructA implements From<StructB>, and StructB implements From<S>.

How can I generically implement a 'shortcut' Into<StructA> for S or From<S> for StructA?

If this is a bad idea, please do tell. But kindly explain how to do it anyway for the sake of learning.

Here's my attempt:

struct StructA {
    f: StructB
}

struct StructB {
    g: i32
}

impl From<StructB> for StructA {
    fn from(v: StructB) -> Self {
        Self {
            f: v
        }
    }
}

impl From<i32> for StructB {
    fn from(v: i32) -> Self {
        Self {
            g: v
        }
    }
}

impl<T: Into<StructA>, S: Into<T>> Into<StructA> for S {
    fn into(self) -> StructA {
        let i: T = self.into();
        i.into()
    }
}

The error I get is the type parameter 'T' is not constrained by the impl trait, self type, or predicates.

I don't understand it. Isn't T constrained by Into<StructA>?

question from:https://stackoverflow.com/questions/65900920/making-a-generic-from-into-shortcut-for-two-steps-from

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The error message basically states that the compiler has no way to infer what type T may be – it basically has to figure out whether any type T exists such that the given trait bounds T: Into<StructA>, S: Into<T> are satisfied, and this is not possible in Rust. One problem with this is, as stated in the comments, that there might be multiple types T satisfying the trait bounds, in which case the compiler can't determine which one to use.

In addition, the Into trait already has a blanket implementation in the standard library.

impl<T, U: From<T>> Into<U> for T;

There is no way for the compiler to guarantee that this impl doesn't overlap with your blanket impl, which would also make the implementation ambiguous.

I recommend you simply implement From<i32> for StructA explicitly. If you need many such implementations, macros could be useful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...