1

我用 Scalatra 写了一个小服务,它做了两件事:

  • 提供 JSON 数据
  • 提供与 Excel 工作表相同的数据

JSON 使用 spray-json、Excel 完成 - 使用 apache POI

基本上,我在 ScalatraServlet 实现中编写了两个方法:

def serveJson[T: JsonWriter](data: T) = {
  contentType = "text/json"
  data.toJson.prettyPrint
}

def serveExcel[T: ExcelWriter](data: T) = {
  contentType = "application/excel"
  data.toExcel.getBytes
}

这里toJson是用spray-json实现的,所以我只是提供了一个JsonWriter隐式转换。所以我决定写一个类似toExcel的转换。

// ExcelWriter.scala

package com.example.app.excel

import org.apache.poi.hssf.usermodel.HSSFWorkbook
import annotation.implicitNotFound

@implicitNotFound(msg = "Cannot find ExcelWriter type class for ${T}")
trait ExcelWriter[T] {
  def write(obj: T): HSSFWorkbook
}

object ExcelWriter {
  implicit def func2Writer[T](f: T => HSSFWorkbook): ExcelWriter[T] = new ExcelWriter[T] {
    def write(obj: T) = f(obj)
  }
}


// Imports.scala
package com.example.app.excel

import org.apache.poi.hssf.usermodel.HSSFWorkbook

object Imports {

  type ExcelWriter[T] = com.example.app.excel.ExcelWriter[T]
  implicit def pimpAny[T](any: T) = new AnyExcelPimp(any)
  private[excel] class AnyExcelPimp[T](any: T) {
    def toExcel(implicit writer: ExcelWriter[T]): HSSFWorkbook = writer.write(any)
  }

}

现在,问题是:

如果我 import import cc.spray.json._,则import excel.Imports._scalac 会抛出错误serveJson(值 toJson 不是类型参数 T 的成员)

如果我导入import excel.Imports._,则import cc.spray.json._scalac 会引发类似的错误serveExcel(toExcel 的值不是类型参数 T 的成员)

令人惊讶的是,如果我只使用其中一个导入,一切都可以编译并正常工作(好吧,一半,因为我注释掉了一半,它使用了删除的导入)。

我的实施有什么问题?

链接到 spray-json 源,我用作参考:https ://github.com/spray/spray-json/tree/master/src/main/scala/cc/spray/json

斯卡拉版本 - 2.9.2

4

1 回答 1

1

问题似乎是我使用的隐式转换名称与 spray-json: 中使用的名称相同pimpAny

// my implicit
implicit def pimpAny[T: ExcelWriter](any: T) = new AnyExcelPimp(any)

// spray-json implicit
implicit def pimpAny[T](any: T) = new PimpedAny(any)

所以一个简单的重命名解决了这个问题。

尽管如此,在编译时看不到根本问题但结果还是有点奇怪。估计要睡了...

于 2012-09-04T19:57:27.940 回答