4

関数から型を返したい。例えば:

class Super
case class One(a: Int) extends Super
case class Two(b: Float) extends Super
case class Unknown extends Super

def decide(criterion: String): ??? = {
  criterion match {
    case "one" => One
    case "two" => Two
    case _ => Unknown
  }
}

だから私はタイプ自体を返し、後でどこかに適用できるようにそれをマップに保存したいと思います。

val test = Buffer(
  ("ahaha" -> "one")
  ("ohoho" -> "two")
  ("lalala" -> "one")
)

var map = scala.collection.mutable.Map[String, Super]()

test.map {pair =>
  map(pair._1) = decide(pair._2)
}

後で私は好きになることができます:

def act(code: String) {
  map(code) match {
    case One => doSmth[One]()
    case Two => doSmth[Two]()
    case _ => doNothing()
  }
}

ケースクラスの未使用のパラメータなど、一部の部分がここでは奇妙に見えるかもしれませんが、これは私が作業している環境での状態です。この例は、私が何かを奪う...

では、decide関数が型を返すようにして、それを私が示したのと同じように使用するにはどうすればよいでしょうか。

4

2 に答える 2

4

case object OneClassやClassTagを使用するのではなく、などが必要になると思います。次に、便利なマッチサポートを取得します。このactメソッドの場合、ケースオブジェクトはClassTagなどを返すか、actにOneをdoSmth[OneClass]などに関連付けさせることができます。

ケースコンパニオンをケースオブジェクトにできるようです。それは特別なことではありません。

package typeswitch
import reflect.runtime.universe._

sealed trait Selection

class Super
case class One(a: Int) extends Super
case object One extends Selection
case class Two(b: Float) extends Super
case object Two extends Selection
case class Unknown() extends Super
case object Unknown extends Selection

object Test extends App {
  type What = Selection

  def decide(criterion: String): What = criterion match {
    case "one" => One
    case "two" => Two
    case _ => Unknown
  }

  val test = List(
    "ahaha" -> "one",
    "ohoho" -> "two",
    "lalala" -> "one"
  )

  val m = scala.collection.mutable.Map[String, What]()

  test map (pair => m(pair._1) = decide(pair._2))

  def act(code: String) = m(code) match {
    case One => doSmth[One]()
    // non-exhaustive
    //case Two => doSmth[Two]()
    case Unknown => doNothing()
    // handle exhaustively
    case s: Selection => doSmthNew(s)
  }
  def doSmthElse[A <: Super]()(implicit t: TypeTag[A]): A = {
    Console println s"Do st with $t"
    val claas: Class[_] = t.mirror.runtimeClass(t.tpe)
    null.asInstanceOf[A]
  }
  def doSmth[A <: Super]()(implicit t: ClassTag[A]): A = {
    Console println s"Do st with $t"
    val claas: Class[_] = t.runtimeClass
    null.asInstanceOf[A]
  }
  def doSmthNew[A >: What : ClassTag, B <: Super](what: A): B = {
    Console println s"Do st new with $what"
    null.asInstanceOf[B]
  }
  def doNothing() { }

  val res = act("lalala")
  Console println s"Got $res?"
}
于 2012-12-10T17:19:56.453 に答える
3

これが基本的すぎる場合は申し訳ありませんが、次のようになります。

$ scala
Welcome to Scala version 2.10.0-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_06).
Type in expressions to have them evaluated.
Type :help for more information.

scala> trait Bar
defined trait Bar

scala> case class Foo(i:Int) extends Bar
defined class Foo

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> def f[A <: Bar : TypeTag]() = println(s" Do ${ implicitly[TypeTag[A]] }") 
f: [A <: Bar]()(implicit evidence$1: reflect.runtime.universe.TypeTag[A])Unit

scala> f[Foo]
 Do TypeTag[Foo]
于 2012-12-10T18:15:16.090 に答える