1

我创建了一个由类型参数参数化的 DSLRow

trait ExtractorSyntax[Row] {
  def extract[A1, A2](e1: Extractor[Row, A1], e2: Extractor[Row, A2]) =
    new Tuple2Extractor[Row, A1, A2](e1, e2)

  def extract[A1, A2, A3](e1: Extractor[Row, A1], e2: Extractor[Row, A2], e3: Extractor[Row, A3]) =
    new Tuple3Extractor[Row, A1, A2, A3](e1, e2, e3)

  // More implementations
}

使用它时,您可以混合ExtractorSyntax指定Row类型。例如

import java.sql.ResultSet

class MyExtractors extends ExtractorSyntax[ResultSet] {
  val extractor1: Extractor[ResultSet, String] = ???
  val extractor2: Extractor[ResultSet, Int] = ???
  val extractor3: Extractor[ResultSet, String] = ???

  // This works fine
  val myExtractor = extract(extractor1, extractor2, extractor3)
}

使用它的另一种方法是创建一个扩展 ExtractorSyntax 的对象并将其导入:

import java.sql.ResultSet

object MyExtractorSyntax extends ExtractorSyntax[ResultSet]

import MyExtractorSyntax._

class MyExtractors {
  val extractor1: Extractor[ResultSet, String] = ???
  val extractor2: Extractor[ResultSet, Int] = ???
  val extractor3: Extractor[ResultSet, String] = ???

  // This works fine
  val myExtractor = extract(extractor1, extractor2, extractor3)
}

但是,如果您决定用它扩展一个包对象,则它无法编译

// File 1
package test

import java.sql.ResultSet

object `package` extends ExtractorSyntax[ResultSet]

// File 2
package different

import test._

class MyExtractors {
  val extractor1: Extractor[ResultSet, String] = ???
  val extractor2: Extractor[ResultSet, Int] = ???
  val extractor3: Extractor[ResultSet, String] = ???

  // This fails to compile
  val myExtractor = extract(extractor1, extractor2, extractor3)
}

不幸的是,此时编译失败,每个提取器都出现相同的错误:

type mismatch;
[error]  found   : sqlest.extractor.Extractor[java.sql.ResultSet,String]
[error]  required: sqlest.extractor.Extractor[Row,?]
[error]   val myExtractor = extract(extractor1, extractor2, extractor2)
[error]                             ^

这很奇怪,因为ResultSet已将其指定为类型参数ExtractorSyntax,但编译器却要求Row.

这里发生了什么?

4

0 回答 0