首页 文章

Scala:反对命名参数

提问于
浏览
1

我正在尝试将命名参数传递给常规Scala对象(如string / list / map)中的函数,其中参数的名称及其值都是可变的(在我的情况下来自解析的用户输入) . 有没有办法在Scala中执行此操作?我主要在scala中寻找一个简短的程序,类似于python中的这个:

def surprise(animal, color):
    print('Oh, a ' + color + ' ' + animal + '!')

arguments = {'animal': 'cat', 'color': 'black'}
surprise(**arguments)

由于python可以将字典解压缩为命名参数,因此可以实现

Oh, a black cat!

我一直在scala中搜索这个功能,但我找不到它 . 任何人都可以举例说明如何在scala中实现这一目标吗?

提前致谢!

1 回答

  • 1

    我会说,它并不像python那么容易,但我会尝试提出几种解决方案 . 您需要从类型和顺序的json(或其他用户输入)中提取参数 . 可以使用例如helper case class和play-json来完成它:

    def surprise(animal: String, color: String): Unit = {
      println(s"Oh, a $color $animal!")
    }
    
    import play.api.libs.json.{JsValue, Json}
    
    case class FuncArguments(animal: String, color: String)
    implicit val funcArgumentsFormat = Json.format[FuncArguments]
    
    implicit def jsValueToFuncArguments(json: JsValue): FuncArguments =
      json.as[FuncArguments]
    
    def surprise2(json: JsValue): Unit = {
      (surprise _).tupled(FuncArguments.unapply(json).get)
    }
    

    case类与您的方法具有相同的签名 . implicit val funcArgumentsFormat 是play-json格式,用于将数据提取到case类中(不安全,因为 as . 如果在json中缺少必需的参数名称/类型,将抛出异常),隐式def jsValueToFuncArguments将你的json转换为case类(理论上也不安全,因为 Option.get ,但不要以为你可以在这里得到异常) . 并帮助函数surprise2将json转换为参数 .

    例如,另一种方法是使用一些反射:

    import play.api.libs.json.{JsValue, Json}
    
    class SomeClass {
      def surprise(animal: String, color: String): Unit = {
        println(s"Oh, a $color $animal!")
      }
    }
    
    def surprise3(json: JsValue): Unit = {
      val method = classOf[SomeClass].getMethods.find(_.getName == "surprise").get
      val params = method.getParameters
      val values = params.map(_.getName).map(name => (json \ name).as[String])
      val ref = new SomeClass
      method.invoke(ref, values: _*)
    }
    

    在这个例子中,我们假设所有字段都具有相同的类型 String ,您的函数在类中 . Play-json用于解析 . 获取方法而不是参数名称,而不是提取参数的值(与参数的顺序相同),而不仅仅是将它们应用于函数 .

    并致电:

    val json = Json.obj("animal" -> "cat", "color" -> "black")
    
    surprise2(json)
    surprise3(json)
    

相关问题