2012-01-30 34 views
3

我在Scala中编写了一些代码,它依赖于我无法在参数上看到的类型参数。是否可以匹配Scala中的清单类型?

def read[T](json: String)(implicit m: Manifest[T]): T = { 
    if (m <:< manifest[Map[String, Any]]) { 
    JsonParser.jsonToMap(json).asInstanceOf[T] 
    } else { 
    throw new UnsupportedOperationException("Not implemented for type %s".format(m)) 
    } 
} 

除了事实,我写我自己的JSON的框架,这可能是一个非常糟糕的主意......

我可以用它代替的if语句case语句,或者我应该在不同的方向思考?

回答

6

在类似这些情况下,您更喜欢使用针对清单或类的测试序列(或更常用的类型套接字),这种情况下更好的想法是使用类型类。在这种特殊情况下,它看起来像,

// Type class 
trait JsonReader[T] { 
    def apply(json : String) : T 
} 

// Type class instance for type Map[String, Any] 
implicit def mapReader = new JSonReader[Map[String, Any]] { 
    def apply(json : String) = 
    JsonParser.jsonToMap(json).asInstanceOf[Map[String, Any]] 
} 

def read[T](json : String)(implicit reader : JsonReader[T]) : T = reader(json) 

您应该为所有您关心的类型添加类型实例。

您现在可以叫你读功能如下,

read[Map[String, Any]](... some json ...) 

需要注意的是,现在,如果你试图用对应于您已不提供类型的类实例的一个类型的类型参数来调用它结果在编译时将是错误的,而不是在运行时的UnsupportedOperationException

+0

很好的答案,谢谢! – iwein 2012-02-10 06:19:50