我不时会处理包含以下内容的java:
def printDbl(d:Double) { println("dbl: " + d) }
def printInt(i:Int) { println("int: " + i) }
很自然地,我想把它包装成一些scala,最终看起来像这样:
def print[T:Manifest] (t:T) {
if (manifest[T] <:< manifest[Int]) { printInt(t.asInstanceOf[Int]) ; return }
if (manifest[T] <:< manifest[Double]) { printDbl(t.asInstanceOf[Double]) ; return }
throw new UnsupportedOperationException("not implemented: " + manifest[T])
}
但是当我运行以下内容时,我得到一个运行时异常:
print(1)
print(2.0)
print("hello")
我似乎记得有一种方法可以在编译时捕获它,但我似乎无法谷歌。也许是一些聪明的隐含转换?
答案 0 :(得分:6)
为什么不直接利用方法重载并编写这样的Scala包装器?:
object Printer {
def print(d: Double) { printDbl(d) }
def print(i: Int) { printInt(i) }
}
这很简单,并提供了所需的行为:
import Printer._
print(1.) // dbl: 1.0
print(1) // int: 1
print("hello") // compile-time type error
答案 1 :(得分:1)
scala> object SpecType {
| trait SpecType[T] {
| def is(s: String): Boolean
| }
| implicit object DoubleType extends SpecType[Double] {
| def is(s: String) = s == "Double"
| }
| implicit object IntType extends SpecType[Int] {
| def is(s: String) = s == "Int"
| }
| }
defined module SpecType
scala> import SpecType._
import SpecType._
scala> def print[T: SpecType](x: T) {
| if(implicitly[SpecType[T]].is("Int")) println("Int")
| if(implicitly[SpecType[T]].is("Double")) println("Double")
| }
print: [T](x: T)(implicit evidence$1: SpecType.SpecType[T])Unit
scala> print(1)
Int
scala> print(1.0)
Double
scala> print("")
<console>:21: error: could not find implicit value for evidence parameter of typ
e SpecType.SpecType[String]
print("")
答案 2 :(得分:0)
这是我提出的最好的
class CanPrint[T] (t:T) { def getT = t}
implicit def canPrint(i:Int) = new CanPrint[Int](i)
implicit def canPrint(d:Double) = new CanPrint[Double](d)
def print[T:Manifest] (t:CanPrint[T]) {
if (manifest[T] <:< manifest[Int]) { printInt(t.getT.asInstanceOf[Int]) ; return }
if (manifest[T] <:< manifest[Double]) { printDbl(t.getT.asInstanceOf[Double]) ; return }
throw new UnsupportedOperationException("not implemented: " + manifest[T])
}
以下内容无法编译
print(1)
print(1.0)
print("hello")
以下是我所期待的
print(1)
print(1.0)
然而,这是错误的代码,因为我必须导入隐式defs才能工作,并且作为此代码的使用者我所看到的是方法签名,说我必须传入一个CanPrint对象,我可以实例。
print(new CanPrint("hello")) // pwned
我可以将构造函数设为私有,只能访问隐式方法或某些方法吗?
答案 3 :(得分:0)
def printDbl(d:Double) { println("dbl: " + d) }
def printInt(i:Int) { println("int: " + i) }
trait Printer[T] { def print(t:T) }
class PD extends Printer[Double] { def print(d:Double) = printDbl(d) }
class PI extends Printer[Int] { def print(i:Int) = printInt(i) }
implicit val pd = new PD()
implicit val pi = new PI()
def print[T](t:T)(implicit printer:Printer[T]) = printer.print(t)
print(1) // 1
print(2.0) // 2.0
print("hello") // Error:(88, 7) could not find implicit value for parameter printer: A$A336.this.Printer[String]