如何创建参数化函数以检查各种类型的值

时间:2018-10-20 03:51:51

标签: scala

假设我必须检查从文件中读取的名称/值对的哈希图中的值,以查看这些值是否满足某些要求或约束。

val hm: mutable.HashMap[String, String] = mutable.HashMap()
hm.put("abc", 123)
hm.put("def", "xYx") 

我想写下面的简单支票。例如,

evaluate("abc", 125, (x,y) => x == y)  // see if value of "abc" is equal to 125 (integer)
evaluate("def", "xyz", (x,y) => x.toLowerCase == y) // sse if the value of def is equal to xyz (all lower case) 
evaluate("abc", 400, (x,y) => x > y) // see if value is greater than 400

我尝试如下创建评估函数

def evaluate[T](p: String, expVal: T, f: (T, T) => Boolean): Boolean =  {
    if (!hm.contains(p)) false

    typeOf[T] match {
        case t if t =:= typeOf[String] => f(hm(p), expVal)
        case t if t =:= typeOf[Int] => f(hm(p).toInt, expVal)
        case _ => false
    }
}

运行以上命令,我得到

Error:(16, 11) No TypeTag available for T
    typeOf[T] match {

Error:(16, 11) not enough arguments for method typeOf: (implicit ttag: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type.
    Unspecified value parameter ttag.
    typeOf[T] match {

Error:(17, 45) type mismatch;
  found   : String
  required: T
  case t if t =:= typeOf[String] => f(hm(p), expVal)

我想知道您是否对评估功能有更好的建议。

先谢谢了。

1 个答案:

答案 0 :(得分:1)

您的Map类型为[String, String],因此您始终会从中获得类型为String的值。因此,您尝试测试值的类型并不会成功,因为它始终为String

如果要保留此映射类型,则需要根据需要转换值,也可以使测试值成为测试函数的一部分,而不是将它们作为单独的参数传递给evaluate

def evaluate(key: String, pred: String => Boolean) =
  hm.get(key).exists(pred)

evaluate("abc", _.toInt == 125) // see if value of "abc" is equal to 125 (integer)
evaluate("def", _.toLowerCase == "xyz") // sse if the value of def is equal to xyz (all lower case)
evaluate("abc", _.toInt > 400) // see if value is greater than 400

如果值不能转换为Int,则第一个和第三个表达式将失败。