Scala从地图中调用lambda

时间:2013-05-06 16:55:25

标签: scala

我有以下代码:

val actions = Map(
"index" ->  Map(
  "description" -> "Makes CAEServer index project with provided project_id "
  , "usage" -> "index project_id"
  , "action" -> (
    (args: Array[String]) => {
      if (checkSecondArgument(args, "Project ID wasn't specified. Please supply project ID.")) {
        new CAEServer(args{0}).index(args{2})
      }
    }
)))

actions{providedAction}{"action"}(args)

当我尝试编译它时,编译器说

error: MainConsole.this.actions.apply(providedAction).apply("action") of type java.lang.Object does not take parameters
[INFO]       actions{providedAction}{"action"}(args)
[INFO]       ^
[ERROR] one error found

怎么了?

1 个答案:

答案 0 :(得分:3)

请记住:Scala是静态类型的。

当您创建(外部)Map时,Scala会根据您放置的内容推断actions的类型。限制性最强但仍匹配的类型(所谓的最小上限)是:

Map[String,Map[String,Object]]

MapStrings映射到Maps,将Strings映射到Objects。因此,当您检索任何元素时,它将是Object类型,而不是Function,因此您无法调用它。

您应该使用案例类:

case class ActionElement(
    description: String,
    usage: String,
    action: Array[String] => CAEServer)

val actions = Map("index" ->  ActionElement(
   "Makes CAEServer index project with provided project_id ",
   "index project_id",
   args => { if (checkSecondArgument(args, "Project ID wasn't ...")) {
     new CAEServer(args{0}).index(args{2})
   }
))

现在你可以致电:

actions(providedAction).action(args)