【问题标题】:functions as values of Map in scala在 Scala 中用作 Map 的值
【发布时间】:2017-04-15 00:06:18
【问题描述】:

我正在尝试在 Scala 中创建 lambda 函数的映射

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)))

当我输入 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: 

貌似函数被覆盖了。到哪里去追求不变性?

【问题讨论】:

  • 看propmap的类型。此外,这个错误是编译时错误,你无法根据它推断出你程序的运行时属性。

标签: scala dictionary


【解决方案1】:

问题是propmap的类型。

Scala 将类型推断为 String,(List[String] => Any)

原因是 scala 需要推断一个匹配所有值的类型。字符串作为键是显而易见的,但是对于函数,它需要找到一个匹配所有函数的函数类型。由于所有函数都有 1 个参数,因此这将是 function1。

如果您查看 function1 的定义,您会发现它是:

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))

第二种解决方案是重写函数以使用 Any,例如:

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

【讨论】:

【解决方案2】:

因为 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))

【讨论】:

  • 你实际上不需要限定 Map 语句,propmap 的原始定义可以工作,你只需要 asInstanceOf
猜你喜欢
  • 2012-04-17
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 2012-02-26
  • 2013-10-21
相关资源
最近更新 更多