मैंने अपनी समस्या को निम्न कोड में कम कर दिया है:

struct Struct<'a, 'b, T> {
    a: &'a T,
    b: &'b T,
}

trait Trait<'a, 'b, T> {
    fn a(&self) -> &'a T;
    fn b(&self) -> &'b T;
}

impl<'a, 'b, T> Trait<'a, 'b, T> for Struct<'a, 'b, T> {
    fn a(&self) -> &'a T {
        self.a
    }
    fn b(&self) -> &'b T {
        self.b
    }
}

struct Confused<T> {
    field: T,
}

impl<T> Confused<T> {
    fn foo<'a, 'b>(&'a self, param: &Struct<'a, 'b, T>) -> &'a T {
        param.b();
        param.a()
    }

    fn bar<'a, 'b, U: Trait<'a, 'b, T>>(&'a self, param: &U) -> &'a T {
        param.b();
        param.a()
    }
}

फ़ंक्शन foo ठीक है, लेकिन जब मैं कंक्रीट प्रकार Struct<'a, 'b, T> को एक सामान्य प्रकार U: Trait<'a, 'b, T> से बदलता हूं, तो मुझे निम्न त्रुटि मिलती है:

error[E0309]: the parameter type `T` may not live long enough
  --> src/lib.rs:31:15
   |
24 | impl<T> Confused<T> {
   |      - help: consider adding an explicit lifetime bound `T: 'b`...
...
31 |         param.b();
   |               ^
   |
note: ...so that the reference type `&'b T` does not outlive the data it points at
  --> src/lib.rs:31:15
   |
31 |         param.b();
   |               ^

बाउंड T: 'b को जोड़ने का सुझाव मेरे लिए कोई मायने नहीं रखता, क्योंकि 'b bar() का एक पैरामीटर है। मैं Trait<'a, 'b, T> के किसी भी कार्यान्वयन को पैरामीटर के रूप में स्वीकार करने के लिए bar() को कैसे ठीक कर सकता हूं?

0
Tavian Barnes 31 मार्च 2020, 17:49

1 उत्तर

सबसे बढ़िया उत्तर

जब आप एक सामान्य प्रकार लिखते हैं जैसे:

struct Foo<'a, T> {
    a: &'a T,
}

जंग स्वचालित रूप से T: 'a प्रकार का एक अंतर्निहित प्रतिबंध जोड़ता है, क्योंकि T के लिए आपका संदर्भ T से अधिक समय तक नहीं रह सकता है। यह स्वचालित है क्योंकि इसके बिना आपका प्रकार काम नहीं करेगा।

लेकिन जब आप कुछ ऐसा करते हैं:

impl<T> Foo {
    fn bar<'a, 'b>() -> &'a T {/*...*/}
}

एक स्वचालित T: 'a है लेकिन T: 'b नहीं है क्योंकि कहीं भी कोई &'b T नहीं है।

समाधान उन बाधाओं को अपने आप से जोड़ना है। आपके कोड में यह कुछ ऐसा होगा:

impl<T> Confused<T> {
    fn bar<'a, 'b, U: Trait<'a, 'b, T>>(&'a self, param: &U) -> &'a T
    where
        T: 'b, //<--- here!
    {
        param.b();
        param.a()
    }
}

3
rodrigo 31 मार्च 2020, 15:36