2016-10-21 5 views
0

Ich bin ein Programm in scala Schreiben, die einen Rahmen um verwendet:Scala - Verwenden komplizierter Generika, um Informationen einer Unterklasse und einer anderen Klasse zu erhalten - kompiliert nicht?

trait Tool[T <: Tool[T, U], U <: Settings[T]] { 
    // members here 
    def createSettingsFrom(settingsWithStringNames: Map[String, _]): U 
} 

trait Settings[T <: Tool[T, _ <: Settings[T]] 

In-Tool, T die Unterklasse, und U ist eine Klasse, die Informationen für die es trägt. Jedes Tool kann als eine Art Befehl mit Parametern betrachtet werden, und diese Parameter sind für jeden von ihnen benutzerdefiniert.

Ich habe auch eine Klasse, die sie zusammen mit ihrem „Informationsträger“ erweitert:

object Cleanup extends Tool[Cleanup, CleanupSettings] { 
    override def createSettingsFrom(settings: Map[String, _]): CleanupSettings 
    = CleanupSettings(
     settings.get("attribute1").asInstanceOf[Int] 
     settings.get("attribute2").asInstanceOf[String]) 
} 

case class CleanupSettings extends Settings[Cleanup](
    //attribute1: Int, 
    //attribute2: String 
    //more attributes) 

Wenn ich versuche, diese Klassen zu kompilieren, erhalte ich die folgende Stacktrace:

Information:21/10/16 03:20 - Compilation completed with 2 errors and 0 warnings in 3s 200ms /project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/Cleanup.scala Error:(17, 24) type arguments [package.tools.operations.cleanup.Cleanup,package.tools.operations.cleanup.CleanupSettings] do not conform to trait ConfigurableTool's type parameter bounds [T <: package.tools.ConfigurableTool[T,U],U <: package.tools.params.Settings[T]] object Cleanup extends ConfigurableTool[Cleanup, CleanupSettings] { ^ /project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/CleanupSettings.scala Error:(11, 11) type arguments [package.tools.operations.cleanup.Cleanup] do not conform to trait Settings's type parameter bounds [T <: package.tools.Tool[T, _ <: package.tools.params.Settings[T]]] extends Settings[Cleanup] ^

Ich habe auch eine Eigenschaft ConfigurableTool, die nur eine Erweiterung des Tools mit einigen zusätzlichen Funktionen ist, so dass es genau die gleiche generische Signatur und es nur extends Tool[T, U] hat.

Ich habe mehrere Dinge versucht, um das Problem zu lösen, einschließlich Hinzufügen von Kombinationen von + und - zu meinen Generika für Co-und Kontravarianz, aber es hilft nicht. Ich habe einen dynamischen Typ für meine Einstellungen in Betracht gezogen, aber Geschwindigkeit ist ein bisschen ein Faktor. Ich weiß nicht einmal, ob es das Problem lösen würde, wenn ich es täte.

Das ist es wirklich, ich hoffe, dass Sie etwas Zeit haben, um meinen Fall zu helfen, wenn nicht, danke fürs Lesen sowieso!

Antwort

0

Ich kann die Fehlermeldung, die Sie erhalten haben, nicht reproduzieren.

Es gibt ein paar Tippfehler im Code, aber nach dem Bereinigen ist der einzige verbleibende Fehler in der Definition von Cleanup, den Sie nicht als Typparameter übergeben können, wenn Sie ein Merkmal erweitern.

object Cleanup extends Tool[Cleanup.type, CleanupSettings] { ... } 

illegal zyklische Referenz Beteiligung Objekt Cleanup

Sie können rund um das erhalten, indem es ein Merkmal zu machen und es in dem Begleitobjekt erstreckt. Hier ist der vollständige Code:

trait Tool[T <: Tool[T, U], U <: Settings[T]] { 
    // members here 
    def createSettingsFrom(settingsWithStringNames: Map[String, _]): U 
} 

trait Settings[T <: Tool[T, _ <: Settings[T]]] 

trait Cleanup extends Tool[Cleanup, CleanupSettings] { 
    override def createSettingsFrom(settings: Map[String, _]): CleanupSettings = CleanupSettings(
    settings.get("attribute1").asInstanceOf[Int], 
    settings.get("attribute2").asInstanceOf[String]) 
} 
object Cleanup extends Cleanup 

case class CleanupSettings(
    attribute1: Int, 
    attribute2: String) extends Settings[Cleanup] 
+0

Oh, das ist sehr cool. Am Ende habe ich den Parameter des Unterklasse-Typs entfernt, um ihn zu vereinfachen. Ich habe festgestellt, dass das Verweisen auf Cleanup nicht dasselbe ist wie das Verweisen auf seine Klasse, aber das ist ein guter Workaround für die zyklische Referenz. Vielen Dank :) – Dico

Verwandte Themen