Scala类型推断忽略包对象中提供的类型

时间:2015-02-09 14:50:51

标签: scala type-inference type-parameter scala-2.11

我创建了一个由类型参数Row

参数化的DSL
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类型。 e.g。

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

这里发生了什么?

0 个答案:

没有答案