Scala的编译时类型常量使用模式匹配

时间:2014-08-02 05:17:51

标签: scala types

我使用代数数据类型(案例对象)来表示在模式加工中使用它们的类型。

sealed trait PrimitiveType
case object IntType extends PrimitiveType
case object LongType extends PrimitiveType
case object StringType extends PrimitiveType
...

def valueType(key: String): PrimitiveType = {
  "NAME" => StringType
  "AGE" => IntType
  ...
}

def read(db: Database, key: String): Unit = valueType(key) match {
  case IntType => send(db.parseIntField(database, key))
  case LongType => send(db.parseLongField(database, key))
  case StringType => send(db.parseStringField(database, key))
  ...
}

但是您知道,Scala中已经有IntLongString等等。
我认为定义几个案例对象来代表这些是浪费 我想将IntTypeLongType,...更改为Int.typeLong.type或我可以在模式匹配中使用的任何内容。

在这种情况下有什么效率?
classOftypeOfTypeTagClassManifest,...但我无法看到它们之间的确切差异。

我使用Scala 2.11,因此TypeTag如果在这种情况下有效则可以。

2 个答案:

答案 0 :(得分:2)

对于这种情况(即你只处理原始类型而不关心泛型)所有这些都可以正常工作。除了在新项目中使用清单之外没有意义。例如。带有typetags:

import scala.reflect.runtime.universe._

val TypeTagString = typeTag[String]

def valueType(key: String): TypeTag[_] = {
  "NAME" => TypeTagString
  "AGE" => TypeTag.Int
  ...
}

def read(db: Database, key: String): Unit = valueType(key) match {
  case TypeTag.Int => send(db.parseIntField(database, key))
  case TypeTag.Long => send(db.parseLongField(database, key))
  case TypeTagString => send(db.parseStringField(database, key))
  ...
}

但是,我会考虑回到最初的设计并稍微改变一下:

sealed trait PrimitiveType[T] {
  def parseField(db: Database, key: String): T
}
case object IntType extends PrimitiveType[Int] {
  def parseField(db: Database, key: String) = db.parseIntField(key)
}
...

def read(db: Database, key: String): Unit = valueType(key).parseField(db, key)

答案 1 :(得分:1)

您可以按如下方式使用TypeTag对象和模式匹配:

import scala.reflect.runtime.universe._

val TypeTagString = typeTag[String]

def valueType(key: String): TypeTag[_] = key match {
    case "NAME" => typeTag[String]
    case "AGE" => TypeTag.Int
}

def read(key: String): Unit = valueType(key) match {
    case TypeTag.Int => println("It is an Int") 
    case TypeTagString => println("It is a String")
                          // replaced db access with println for simplicity.
}

但从根本上说,在这里使用typetags没有任何优势。它类似于:

def valueTypes(key: String): Any = key match {
    case "NAME" => "NAME"
    case "AGE" => 0
}

def read(key: String): Unit = valueTypes(key) match {
    case 0 => println("It is an Int")
    case "NAME" => println("It is a String")
}

或简单地说:

def read(key: String): Unit = key match {

    case "NAME" | "COUNTRY" | ... => println("A string")
    case "AGE" => println("An Int")
}