Scala вызвать метод применения объекта, используя строку - PullRequest
1 голос
/ 04 августа 2020

У меня есть класс MyFilter , который имеет много разных версий. В зависимости от входной версии я хочу вызвать этот объект и применить этот фильтр. Пример показан ниже:

object v1{
  def apply(l: List[String]) = {
    l.filter(_.contains("v1"))
  }
}

object v2{
  def apply(l: List[String]) = {
    l.filter(_.contains("v2"))
  }
}

object MyFilter {
  
  def apply(version: String) = (l: List[String]) => {
    println("Applying Filter")
    version match {
      case "v1" => v1(l)
      case "v2" => v2(l)
      case _ => 
    }
  }
}


val df = List("a-v1", "b-v1", "c-v2", "d-v2")
println(MyFilter("v1")(df))
println(MyFilter("v2")(df))

Теперь, если у меня много версий, будет длинный список case в совпадении . Как я могу этого избежать и напрямую вызвать apply метод Object , используя переданную версию, которая является строкой. Было бы здорово, если бы кто-нибудь мог помочь.

1 Ответ

1 голос
/ 20 августа 2020

Вы можете попробовать макрос

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

object MyFilter {    
  def apply(version: String): List[String] => List[String] = macro applyImpl

  def applyImpl(c: blackbox.Context)(version: c.Tree): c.Tree = {
    import c.universe._

    val q"${versionStr: String}" = version

    q"""(l: List[String]) => {
      println("Applying Filter")
      ${TermName(versionStr)}.apply(l)
    }"""
  }
}

Использование:

println(MyFilter("v1")(df))
println(MyFilter("v2")(df))

//scalac: ((l: List[String]) => {
//  println("Applying Filter");
//  v1.apply(l)
//})
//scalac: ((l: List[String]) => {
//  println("Applying Filter");
//  v2.apply(l)
//})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...