我的项目包中有一个流程结构:
mypackage/
package1/
...
package.scala
package2/
...
package.scala
package3/
...
package.scala
在package1 / package.scala中:
package object package1 {
val checkMap = Map("a" -> 1)
}
在package2 / package.scala中:
package object package2 {
val checkMap = Map("b" -> 2)
}
在package3 / package.scala中:
package object package3 {
val checkMap = Map("c" -> 3)
}
(我已经简化了演示的实际代码)
在其他地方我的项目我有这个愚蠢的代码:
class CheckThis(packageName: String) {
var checkerMap = Map[String, Int]()
if (packageName == "package1"){
import com.some.some_prj.mypackage.package1.checkMap
checkerMap = check
} else if (packageName == "package2"){
import com.some.some_prj.mypackage.package2.checkMap
checkerMap = check
} else if (packageName == "package3"){
import com.some.some_prj.mypackage.package3.checkMap
checkerMap = check
def checker(val: String) = checkerMap.getOrElse(val, -1)
}
现在我需要将package4
,package5
,package6
...添加到mypackage
如何在import语句中使用参数?
类似的东西:
class CheckThis(packageName: String) {
import com.some.some_prj.mypackage.$packageName.{checkMap => checkerMap}
或者可能存在import语句的功能变体:
class CheckThis(packageName: String) {
val checkerMap:Map[String, Int] = import(s"com.some.some_prj.mypackage.$packageName.checkMap"}
答案 0 :(得分:2)
不,不是没有诉诸宏或操纵类加载,无论你做什么都可能是一种过度杀伤。
以下是the SLS第4.7章中导入语句的完整子语法:
Import ::= ‘ import ’ ImportExpr {‘,’ ImportExpr}
ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors)
ImportSelectors ::= ‘{’ {ImportSelector ‘,’}
(ImportSelector | ‘_’) ‘}’
ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’]
正如您所看到的那样,无法插入参数化的东西。您必须坚持使用原始的基于样板的方法,或者使用替代方法(根据您的“检查器”代码结构的实际情况选择方式)。
答案 1 :(得分:1)
在Scala中,无法在运行时生成import语句,所有导入都在编译时解析。对于这样的用例,很容易使用包含值的Map来确定应该执行的代码(甚至代码本身以函数的形式):
// R is the return value
val m = Map[String, () => R] = {
val block1 = { () =>
doSomething()
doSomethingElse()
ret
}
val block2 = { () =>
doSomething()
doSomethingElse()
ret2
}
Map("package1" -> block1, "package2" -> block2)
}
val f = m(packageName)
// execute code here and use return value if necessarey
val ret = f()