2

時々、私は次のようなものが含まれている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")

コンパイル時にこれをキャッチする方法があったことを思い出しているようですが、グーグルで検索できないようです。おそらくいくつかの巧妙な暗黙の変換?

4

4 に答える 4

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
于 2012-04-26T04:37:28.533 に答える
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("")
于 2012-04-26T05:54:11.197 に答える
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)

ただし、これを機能させるには暗黙のdefをインポートする必要があるため、これは悪いコードです。このコードのコンシューマーとして表示されるのは、インスタンス化できるCanPrintオブジェクトを渡す必要があることを示すメソッドシグネチャだけです。

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

コンストラクターをプライベートにして、暗黙のメソッドなどにのみアクセスできるようにすることはできますか?

于 2012-04-26T17:46:03.243 に答える
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]
于 2016-02-11T16:51:54.967 に答える