2017-09-16 3 views
0

Ich bin ziemlich neu in der Scala-Programmierung. Neben Scala habe ich nie funktionale Programmierung gelernt. Mit dem gesagt, ich versuche derzeit, einen guten Weg zu finden, um Eigenschaften, Klassen, usw. auf einem Projekt zu definieren, das glatt verwendet.Generischen TableQuery-Typ für Elterneigenschaft verwenden

Meine Idee war, eine Eigenschaft zu haben, die die Methoden hat, die auf den Kindklassen implementiert werden, und einige würden auf der Elternklasse selbst implementiert werden. Ich habe einen Weg gefunden, der funktioniert, aber ich habe keine Ahnung warum. Ich bin mir nicht sicher, ob dieses Problem damit zusammenhängt, wie Slick oder Scala funktioniert.

ich wie eine Konstruktion wurde mit:

trait CompanyDAO extends BaseDao[Company]{ 
self: DBProfile => 

Aber den folgenden Typenkonflikt Fehler geben:

[error] found : slick.lifted.TableQuery[CompanyDAO.this.CompanyTable] [error] required: slick.lifted.TableQuery[CompanyDAO.this.profile.api.Table[Company]] [error] (which expands to) slick.lifted.TableQuery[CompanyDAO.this.profile.Table[Company]] [error] Note: CompanyDAO.this.CompanyTable <: CompanyDAO.this.profile.api.Table[Company], but class TableQuery is invariant in type E. [error] You may wish to define E as +E instead. (SLS 4.5) [error] override def toTable = TableQuery[CompanyTable]

Aber wenn ich

verwenden
self: DBProfile with BaseDao[Company] => 

Dann wird die Zusammenstellung Werke (BTW, bekam die Lösung von another post)

Also, meine Fragen:

1) Warum Totable Zuordnung Werke Selbsttypen verwenden, während das Merkmal erstreckt nicht? Wie interpretiert scala den Typ von toTable in beiden Szenarien?

2) Gibt es eine Möglichkeit, das "Merkmal CompanyDAO extends BaseDao" anzupassen, um den Fehler zu beheben?

Vielen Dank im Voraus.

import scala.concurrent.Future 
import slick.basic.DatabaseConfig 
import slick.jdbc.JdbcProfile 

trait DBConfiguration { 
    lazy val config = DatabaseConfig.forConfig[JdbcProfile]("mytrade") 
} 

trait DBProfile { 
    val config: DatabaseConfig[JdbcProfile] 
    val db: JdbcProfile#Backend#Database = config.db 
    val profile : JdbcProfile = config.profile 
} 

trait BaseDao[T <: Any] { 
    self: DBProfile => 

    import profile.api._ 
    import slick.lifted.TableQuery 

    def toTable():TableQuery[Table[T]] 
    def findAll():Future[Seq[T]] = db.run(toTable.result) 
} 

case class Company(name: String, code: Int) 

// If I use the construction like the comment below, it will fail 
//trait CompanyDAO extends BaseDao[Company]{ 
    //self: DBProfile => 

trait CompanyDAO { 
    self: DBProfile with BaseDao[Company] => 
    //import from DBProfile trait 
    import profile.api._ 

    class CompanyTable(tag: Tag) extends Table[Company](tag, "COMPANY") { 

    import slick.ast.BaseTypedType 
    import slick.jdbc.JdbcType 

    def name = column[String]("name") 
    def code = column[Int]("code") 

    def * = (name, code) <> (Company.tupled, Company.unapply) 
    } 

    override def toTable = TableQuery[CompanyTable] 
} 

EDIT: einige andere Dinge, die ich versucht haben

BaseDao erweitern, wenn ich die Erklärung von Totable ändern:

def toTable[S <: TableQuery[Table[_]]]():S 

Die Typenkonflikt geht weg, aber ich erhalte jetzt :

test.scala:27: dead code following this construct [error] def findAll():Future[Seq[T]] = db.run(toTable.result)

Versucht auch mit Selbst-Typ a Und es gab mir den gleichen Fehler.

+0

1) https: // stackoverflow.com/questions/2224932/Differenz-zwischen-Merkmal-Vererbung-und-Selbst-Typ-Annotation 2) https://stackoverflow.com/questions/1990948/what-is-the-difference-between-self-types- and-trait-subclasses 3) https://softwareengineering.stackexchange.com/questions/219038/what-is-the-difference-between-self-types-and-trait-inheritance-in-scala –

Antwort

0

If I change the declaration of toTable to:

def toTable[S <: TableQuery[Table[_]]]():S

The type mismatch goes away but I receive now:

test.scala:27: dead code following this construct [error] def findAll():Future[Seq[T]] = db.run(toTable.result) 

Any ideas why is this happening?

Ich kann Ihren spezifischen Kompilierungsfehler nicht reproduzieren.

Aber wenn ich die Zeile

def toTable():TableQuery[Table[T]] 

zu

def toTable[S <: TableQuery[Table[_]]]():S 

ich kompilieren Fehler

Error:(24, 51) value result is not a member of Nothing 
    def findAll():Future[Seq[T]] = db.run(toTable.result) 

Dies liegt daran, Typ Parameter S geschlossen wird Nothing zu sein.

Sie bieten keine Implementierung für die Methode toTable und Nothing <: TableQuery[Table[_]].

+0

Vielen Dank für die Referenzen, wirklich hilfreich. Als Referenz verwende ich Scala 2.12.1 mit Slick 3.2.0. Was ich nicht verstehen kann ist, warum toTable(): TableQuery [Table [T]] mit Selbsttypen arbeitet und nicht funktioniert, wenn ich Vererbung verwende. Wie scala interpretiert jeweils den Typ dieser Variablen, was ist die Logik? –

Verwandte Themen