2016-06-02 5 views
7

Ich habe eine Eigenschaft Foo erben von einem anderen Merkmal Bar. Bar hat einen zugehörigen Typ Baz. Foo Constrains Baz so, dass BazHoge implementieren müssen.Erforderlich eine Eigenschaft gebunden an den zugeordneten Typ einer geerbten Eigenschaft

trait Hoge {} 

trait Bar { 
    type Baz; 
} 

trait Foo: Bar where Self::Baz: Hoge {} 

Allerdings, wenn ich eine generische Funktion erfordert der gattungs T definieren Foo,

// [DESIRED CODE] 
fn fizz<T: Foo>(buzz: T) { 
    // ... 
} 

rustc klagt mit EO277 zu implementieren, wenn ich T explizit einschränken:

fn fizz<T: Foo>(buzz: T) where T::Baz: Hoge { 
    // ... 
} 

ich tun verstehe nicht, warum ich das tun muss. Ich möchte gerne [DESIRED CODE] schreiben können. Was ist der empfohlene Weg, dies zu tun?

+0

Wissen Sie, ob 'Merkmal Foo wo ...' konzeptuell gültig ist? Ich sehe, dass es kompiliert *, also ist die Syntax in Ordnung, aber es scheint nur ... seltsam. – Shepmaster

+0

Sie können sich vorstellen, dass ich ein Verhalten des zugehörigen Typs ('Baz') benötige, damit ich, wenn ich' Foo' in einer Implementierung verwende, dieses Verhalten verwenden kann, ähnlich wie man ein Verhalten des geerbten Merkmals benötigen könnte ('Bar'). – Tsukki

+0

Sorry, ich war unklar.Ihre * Absicht * ist verständlich genug (wie es bei metasyntaktischen Variablen wie 'Hoge' sein kann), ich frage meistens, ob Sie jemals eine' Where'-Klausel für eine Merkmalsdefinition gesehen haben, wenn es keine generischen Typen gab; Ich bin mir nicht sicher, ob ich es getan habe. – Shepmaster

Antwort

4

Leider (oder nicht) müssen Sie die Grenzen wiederholen.

Letztes Jahr ein geöffnetes issue, denkend, dass der Typprüfer inkonsistent war. Der Code ist deinem ähnlich.

@ arielb1 geschlossen, die Frage und sagte, dass dies nicht das beabsichtigte Verhalten ist und gab diese Erklärung:

Die Sache ist, dass wir nicht wollen, zu viele Schranken für Funktionen implizit zur Verfügung stehen, da dies kann zu Zerbrechlichkeit mit entfernten Änderungen führen, die dazu führen, dass Funktionen aufhören zu kompilieren. Es gibt grundsätzlich 3 Arten von Grenzen, die für eine Funktion verfügbar sind:

  • Grenzen von expliziten Where-Klauseln - z.B. T: B wenn Sie diese Klausel haben. Dies beinhaltet die "semi-explizite" Sized gebunden.
  • Grenzen von supertraits expliziter where-Klauseln - eine WHERE-Klausel für seine Grenzen supertraits addiert (wie trait B: A die T: B gebunden ein T: A gebundenen hinzufügt).
  • Grenzen von den Lebensdauereigenschaften von Argumenten (Outlives/Implikator/implizierte Grenzen). Dies sind nur lebenslange Grenzen, und irrelevant für das aktuelle Problem. rust-lang/rfcs#1214 beteiligt sie sehr viel.
  • Wenn Ihre Bindung nicht in der Liste enthalten ist, müssen Sie sie explizit hinzufügen, wenn Sie verwenden möchten. Ich denke, das sollte ein FAQ-Eintrag sein.

    Heute habe ich eine issue geöffnet, um diese Informationen zu den Dokumenten zu verlangen.

    +0

    Ich verstehe. Ich stimme dieser Idee, etwas vernünftig erwartetes Verhalten auszuschließen, einfach ab, weil es die Entwicklung von Rust schwieriger machen könnte. Wir sollten herausfinden, was Benutzer eingeben und unser Bestes tun wollen, um dem gerecht zu werden. – Tsukki

    Verwandte Themen