Warum kann sich ein Merkmal nicht selbst konstruieren?

8

Dieser Code gibt mir einen Kompilierungsfehler:

%Vor%

während dieser Code ohne Fehler kompiliert:

%Vor%
  1. Warum kompiliert der erste nicht? rustc --explain E0038 gibt mir keinen direkten Hinweis, warum das nicht möglich ist.
  2. Ist es möglich, Konstruktion und Methoden in einer Schnittstelle (Merkmal) zu kombinieren?
user1244932 02.07.2016, 11:45
quelle

2 Antworten

12

Der Compiler sagt Ihnen den genauen Grund, warum das nicht funktioniert:

%Vor%

Beachten Sie die letzte Zeile. Es besagt, dass der Grund für den Fehler darin besteht, dass new() nicht davon abhängt, dass eine Instanz eines Werts die Eigenschaft IBoo implementiert.

Wenn Sie keinen Zeiger irgendeiner Art auf self setzen, kann die Methode nicht vom dynamischen Dispatch aufgerufen werden. Wenn es nicht vom dynamischen Dispatch aufgerufen werden kann, bedeutet dies, dass es nicht in die verknüpfte vtable des Merkmals gelangen kann. There hat als assoziierte vtable, weil so etwas wie Box<IBoo> funktioniert . Vor einiger Zeit haben die Rust-Kernentwickler entschieden, dass die Verwendung einer einzelnen "nicht-objektsicheren" Methode in einem Merkmal die Verwendung des ganzen Merkmals als Objekt ausschließt.

Um es anders auszudrücken: Da Sie eine Methode definiert haben, die nicht dynamisch ausgelöst werden kann, wird IBoo trait als Ganzes nicht für die dynamische Verteilung verwendet.

>

Wenn Sie irgendeine Art von Konstruktorfunktion wünschen, müssen Sie eine andere Möglichkeit haben, dies zu schreiben. Dies könnte mit einfachen Funktionszeigern oder einem IBooFactory Merkmal geschehen, wie Sie es mit Java tun könnten.

    
DK. 02.07.2016, 12:06
quelle
9

Dies ist aus der Beschreibung von E0038 :

  

Methode hat keinen Empfänger

     

Methoden, die keinen self -Parameter haben, können seitdem nicht aufgerufen werden   Es gibt keine Möglichkeit, einen Zeiger auf die Methodentabelle für sie zu erhalten.

%Vor%      

Dies könnte als <Foo as Foo>::foo() aufgerufen werden, was nicht möglich wäre   um eine Implementierung auszuwählen.

     

Das Hinzufügen einer Self: Sized -Bindung zu diesen Methoden wird dies normalerweise bewirken   kompilieren.

%Vor%

Sie können dies tun:

%Vor%

In anderen Fällen können Sie die Einschränkung auf das gesamte Impl setzen:

    
aSpex 02.07.2016 12:26
quelle

Tags und Links