scala-将泛型类型约束到特定类型

scala-将泛型类型约束到特定类型,scala,Scala,有时,我会处理包含以下内容的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]) ;

有时,我会处理包含以下内容的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])
}

我似乎记得有一种方法可以在编译时捕捉到这一点,但我似乎无法用谷歌搜索它。也许是一些巧妙的隐含转换

为什么不利用方法重载,像这样编写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
scala>对象SpecType{
|性状单体型[T]{
|def是(s:String):布尔值
|   }
|隐式对象DoubleType扩展SpecType[Double]{
|定义为(s:String)=s==“双精度”
|   }
|隐式对象IntType扩展SpecType[Int]{
|定义为(s:String)=s==“Int”
|   }
| }
定义的模块SpecType
scala>导入SpecType_
导入SpecType_
scala>def打印[T:SpecType](x:T){
|if(隐式[SpecType[T]].is(“Int”)println(“Int”)
|if(隐式[SpecType[T]]为(“双”)println(“双”)
| }
打印:[T](x:T)(隐式证据$1:SpecType.SpecType[T])单位
scala>打印(1)
Int
scala>打印(1.0)
双重的
scala>打印(“”)
:21:错误:找不到类型的证据参数的隐式值
e SpecType.SpecType[字符串]
打印(“”)

这是我想到的最好的

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)
然而,这是一段糟糕的代码,因为我必须导入隐式def才能工作,作为这段代码的使用者,我看到的只是方法签名,表示我必须传入一个CanPrint对象,我可以实例化它

print(new CanPrint("hello")) // pwned

我是否可以将构造函数设置为私有的,并且只能由隐式方法或类似的方法访问

我想这段代码可以通过使用Double/Int而不是String来改进,并更改代码的布局,这样您就可以执行如下操作:隐式[SpecType[T]]。println(x)参见这里的示例:
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]
print(1)
print(1.0)
print(new CanPrint("hello")) // pwned
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]