2011-03-16 103 views
15

是否可以匹配Scala中的类型?事情是这样的:scala中的匹配类型

def apply[T] = T match { 
    case String => "you gave me a String", 
    case Array => "you gave me an Array" 
    case _ => "I don't know what type that is!" 
    } 

(但是,编译,显然:))

或许是正确的做法是类型超载......这可能吗?

不幸的是,我不能通过它的一个对象的实例和模式匹配。

回答

21

您可以使用清单并对它们进行模式匹配。但是,传递数组类时的情况有问题,因为JVM对每种数组类型使用不同的类。要解决此问题,您可以检查,如果有问题的类型被删除到数组类:弃用

val StringManifest = manifest[String] 

def apply[T : Manifest] = manifest[T] match { 
    case StringManifest => "you gave me a String" 
    case x if x.erasure.isArray => "you gave me an Array" 
    case _ => "I don't know what type that is!" 
} 
+3

如果删除足够,'ClassManifest'会更快。 – 2011-03-16 23:12:49

+0

'Manifest'已弃用。检查答案:https://stackoverflow.com/a/46706940/1894198 – 2018-01-03 13:56:59

17
def apply[T](t: T) = t match { 
    case _: String => "you gave me a String" 
    case _: Array[_] => "you gave me an Array" 
    case _ => "I don't know what type that is!" 
} 
+1

我无法将它传递给对象的一个​​实例。 – 2011-03-16 20:22:07

+2

要传递对象的实例,请将冒号前面的下划线替换为变量名称。例如:'case s:String =>“你给了我一个字符串”+ s' – 2011-03-16 20:26:22

+4

我的意思是我需要在没有对象实例的情况下调用它,例如'apply [String]',而不是'apply(“字符串“)'。 – 2011-03-16 20:42:45

2

Manifest ID。但你可以使用TypeTag

import scala.reflect.runtime.universe._ 

def fn[R](r: R)(implicit tag: TypeTag[R]) { 

    typeOf(tag) match { 
     case t if t =:= typeOf[String] => "you gave me a String" 
     case t if t =:= typeOf[Array[_]] => "you gave me an Array" 
     case _ => "I don't know what type that is!" 
    } 
} 

希望这会有所帮助。