2017-12-21 113 views
6

मैं दो लक्षण जहां एक-दूसरे की आवश्यकता है लागू किया जाना लिखने का प्रयास किया और यह त्रुटि आई:किसी अन्य विशेषता में सही तरीके से एक विशेषता की आवश्यकता कैसे है?

error[E0277]: the trait bound `T: ValTrait` is not satisfied 
    --> src/main.rs:20:1 
    | 
20 |/fn get<T: ValRequireTrait + std::fmt::Debug>(_t: T) { 
21 | |  println!("{:?}", T::VAL); 
22 | | } 
    | |_^ the trait `ValTrait` is not implemented for `T` 
    | 
    = help: consider adding a `where T: ValTrait` bound 
    = note: required by `ValRequireTrait` 

The code:

trait ValTrait<T = Self> { 
    const VAL: T; 
} 

trait ValRequireTrait<T: ValTrait = Self> {} 

#[derive(Debug, Copy, Clone)] 
struct A { 
    field: u64, 
} 

impl ValTrait for A { 
    const VAL: A = A { 
     field: 0u64 
    }; 
} 
impl ValRequireTrait for A {} 


fn get<T: ValRequireTrait + std::fmt::Debug>(_t: T) { 
    println!("{:?}", T::VAL); 
} 

fn main() { 
    let a = A { field: 6u64 }; 
    get(a); 
} 

कैसे सही ढंग से ऐसा करने के लिए? यदि मैं करता हूं कि संकलक कहता है कि मुझे ValRequireTrait की आवश्यकता नहीं होगी क्योंकि यह बेकार होगा। मैं एक निशान होने के लिए ValRequireTrait चाहता था कि संरचना की आवश्यकता के अनुसार पर्याप्त विधियों को लागू करता है।

दूसरे शब्दों में, मैं ऐसी आवश्यकता इसलिए सकर्मक जा जब get() समारोह में मैं एक विशेषता (ValRequireTrait) की आवश्यकता होती है उम्मीद, दूसरों (ValTrait) कोड संकलक चाहता है के रूप में किसी भी विनिर्देश के बिना स्वचालित रूप से आवश्यक हो जाएगा।

उत्तर

2

ऐसा लगता है कि आप ValTrait एक supertrait ValRequireTrait की होना चाहता हूँ। एक अच्छा परिचय the Rust book (2nd edition) में पाया जा सकता:

Sometimes, we may want a trait to be able to rely on another trait also being implemented wherever our trait is implemented, so that our trait can use the other trait’s functionality. The required trait is a supertrait of the trait we’re implementing.

आप इस लाइन को बदलते हैं:

trait ValRequireTrait<T: ValTrait = Self> {} 

यह करने के लिए, यह ठीक संकलित:

trait ValRequireTrait<T: ValTrait = Self>: ValTrait<T> {} 
+0

मेरे लिए हास्यास्पद लगता है दोहराने एक बात कई बार। क्या ऐसा कोई स्पष्टीकरण है कि ऐसा क्यों किया गया था? मेरा मतलब है, हमें पहले से ही 'टी' को 'वालट्रेट' होने की आवश्यकता है, 'ValRequireTrait' को' ValTrait' क्यों होना चाहिए? मैं यहां दोहराव देखता हूं। –

+0

आपका सही यह अनावश्यक है और संकलक विशेषता सीमाओं का अनुमान लगाने का प्रबंधन करता है। आपको स्पष्ट रूप से विशेषता विशेषता निर्दिष्ट करने की आवश्यकता नहीं है। यह भी काम करता है: 'विशेषता ValRequireTrait : ValTrait {}'। मैं खुद जंगली विशेषज्ञ नहीं हूं, मैं वर्तमान में खुद को सीख रहा हूं। आम तौर पर मैंने पाया कि [आरएफसीएस] (https://github.com/rust-lang/rfcs) में * क्यों * चीजें एक विशिष्ट तरीके से की जाती हैं पर मूल्यवान जानकारी होती है। हालांकि मुझे सुपरट्राइट्स पर कुछ भी प्रासंगिक नहीं मिला। – StarSheriff

+3

@VictorPolevoy 'ValRequireTrait' लगभग बेकार है क्योंकि यह वैसे ही पैरामीटरकृत है 'ValTrait' है। मुझे संदेह है कि आप 'विशेषता ValRequireTrait: आकार + ValTrait {} '(' ValRequireTrait' पर कोई पैरामीटर नहीं) की तलाश कर रहे हैं। [उदाहरण] (https://play.rust-lang.org/?gist=d1a5cbda10d5b63e6082b8caada49911&version=stable) – trentcl

संबंधित मुद्दे