2017-04-15 45 views
0

地图的价值,我想在斯卡拉功能Scala的

val identity = ((x:Any) => x) 
val propmap = Map("references-count" -> identity, 
    "title" -> ((x:List[String]) => x(0)), 
    "score" -> identity, 
    "issued" -> ((x:List[Any]) => x(0))) 

创建地图lambda函数,当我键入propmap("score")propmap("title")输出我得到的是相同的:<function1>

运行identity(10.1)返回预期结果。然而

val f1 = propmap("score") f1(10.9)

结果:

Name: Unknown Error 
Message: <console>:29: error: type mismatch; 
found : Double(10.9) 
required: List[String] 
     f1(10.9) 
     ^
StackTrace: 

貌似功能将被覆盖。在哪里去追求不变性?

+0

看看通用图的类型。此外,这个错误是编译时错误,你不能根据它推断你程序的运行时属性。 – pedrofurla

回答

2

问题是propmap的类型。

Scala的推断类型为字符串,(列表[字符串] =>任何)

其原因是,需要阶来推断哪个匹配所有值的类型。 String作为键是显而易见的,但对于函数,它需要找到一个匹配所有函数的函数类型。由于所有函数都有1个参数,所以这个函数就是function1。

如果你看的功能1,你会看到它的定义是:

trait Function1[-T1, +R] extends AnyRef 

这意味着它需要找到的第一个类型是最紧缩。在这种情况下,这是List [String],因此它需要一个函数List [String] => Any(这实际上是有意义的,因为您需要一个可以在所有函数上使用的类型)。

因此,Scala会在实践中自动将您的身份函数转换为(x:List [String] => x),因此当您尝试传递一个数字时它失败。

可能的解决方案:

第一溶液通过@KotWarm提到将是使用asInstanceOf:

val f1 = propmap("score").asInstanceOf[Any ⇒ Any] 
println(f1(10.9)) 

第二解决方案是重写功能使用的任何,例如:

val propmap = Map("references-count" -> identity, 
        "title" -> ((x: Any) => x.asInstanceOf[List[String]](0)), 
        "score" -> identity, 
        "issued" -> ((x: Any) => x.asInstanceOf[List[Any]](0))) 
+0

如何检查定义? –

+0

在scala文档中:https://www.scala-lang.org/api/current/scala/Function1.html –

1

因为scalac确定收集类型为

propmap: scala.collection.immutable.Map [String, List [String] => Any] 

确定您的收藏类型明确,使编译器知道你想获得

这里什么是一个示例代码

val identity = ((x:Any) => x) 
    val propmap = Map[String,_ => _]("references-count" -> identity, 
     "title" -> ((x:List[String]) => x(0)), 
     "score" -> identity, 
     "issued" -> ((x:List[Any]) => x(0))) 

但执行方法,你必须转换类型

val f1 = propmap("score").asInstanceOf[Any ⇒ Any] 
    println(f1(10.9)) 
+0

实际上,您并不需要限定Map语句,propmap的原始定义可以工作,您只需要asInstanceOf –