2017-09-16 1 views
0

저는 스칼라 프로그래밍에 처음 들어 왔습니다. 스칼라 외에 함수 프로그래밍을 배운 적이 없다. 그렇게 말하면서, 저는 현재 매끄러운 것을 사용하는 프로젝트에서 특성, 클래스 등을 정의하는 좋은 방법을 찾아 내려고 노력 중입니다.상위 특성에 일반 TableQuery 형식 사용

제 아이디어는 자식 클래스에 구현할 메서드가있는 특성을 갖고, 일부는 부모 클래스 자체에서 구현되는 것입니다. 나는 작동하는 방법을 찾았지만 나는 그 이유를 모른다. 이 문제가 Slick 또는 Scala의 작동 방식과 관련이 있는지 확실하지 않습니다.

내가 좋아하는 구성을 사용했다

:

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

그러나 이것은 다음과 같은 유형의 불일치 오류 제공 : 다음

self: DBProfile with BaseDao[Company] => 

컴파일 작업을 사용하는 경우,

[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]

을하지만, (BTW, 해결책을 another post에서 얻었습니다)

그럼 내 질문 :

1) 특성을 확장하는 동안 자체 형식 toTable 할당 작업을 사용하는 이유는 무엇입니까? 두 시나리오에서 scala가 toTable의 유형을 해석하는 방법은 무엇입니까?

2) "특성 CompanyDAO는 BaseDao를 확장"하여 오류를 해결할 수 있습니까?

미리 감사드립니다.

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] 
} 

편집 :

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

유형 불일치가 사라집니다하지만 난 지금 나타납니다 I가 toTable의 선언을 변경하는 경우 나, BaseDao 확장

을 시도하고 다른 것들 :

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

자체 유형을 사용하여 시도했습니다. 그것은 나에게 같은 오류를 주었다.

+0

1) https : // stackoverflow.co.kr/questions/2224932/trait-inheritance-and-self-type-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 –

답변

0

특정 컴파일 오류를 재현 할 수 없습니다.

하지만

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

에 선

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

을 변경할 때 나는 오류를 형식 매개 변수 SNothing 것으로 추정되기 때문이다

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

를 컴파일 할 수 있습니다.

toTableNothing <: TableQuery[Table[_]] 메서드에 대한 구현을 제공하지 않습니다.

+0

감사합니다. 참조, 정말 도움이. 참고로, 저는 Slick 3.2.0에서 Scala 2.12.1을 사용하고 있습니다. 왜 이해할 수없는 이유는 toTable()입니다 : TableQuery [Table [T]]는 자체 유형과 함께 작동하며 상속을 사용하면 작동하지 않습니다. 각각의 경우에 scala가이 변수의 유형을 해석하는 방법은 무엇입니까? –