我想知道是否有办法使用编译时标志(即C系列的#define
的一些粗略等价物)有条件地排除在Scala中编译的代码块。我知道没有直接的对应物,我不认为Scala的宏是我需要的,所以我想知道是否有另一种方法可以做到这一点。
在我目前的情况下(我提供这个仅作为一个例子,因为我过去有其他案例提示相同的问题),我正在ScalaJS中构建一个库。该库是一个前端组件,主要由我的应用程序使用 - 它也使用ScalaJS。但是,我想在其他未使用ScalaJS的项目中允许本机Javascript调用此组件。因此,我希望有一个用户可配置的标志,可以根据请求将符号导出切换为本机Javascript。
默认情况下(在我的应用程序中)导出这些标志是没有意义的,因为调用它的唯一其他代码将是其他ScalaJS代码,因此具有导出符号的开销是没有意义的。维护两个单独的代码分支以实现微不足道的事情似乎也是徒劳的。
这基本上就是我的想法(伪代码,当然):
...
#if JS_EXPORT
@JSExport
#endif
case class componentProps(
#if JS_EXPORT
@(JSExport @field)
#endif
val propertyOne: Int
#if JS_EXPORT
@(JSExport @field)
#endif
val propertyTwo: String
)
...
我很清楚没有预处理器,上面只是伪代码。我只是想知道是否有一种方法可以完成类似的事情,没有不必要的开销,比如使用反射(因为我确信这会提供比默认导出更大的性能)。
此外,我能够找到这个问题:Conditional compilation in Scala。但这不是我需要的。
答案 0 :(得分:2)
在源代码中没有任何方法可以完全破解。
完成双JVM / JS项目的标准方法是尽量减少发生差异的源文件的数量,并为那些人手动完成(几乎所有的Li Haoyi的项目都是这样的 - 检查结构例如fastparse);或者有两个git分支,它们具有两个变体,并将所有变化从一个变为另一个。
答案 1 :(得分:1)
对于您的特定情况,您无需具有特定的源代码:Scala.js提供scalajs-stubs
库。这是一个JVM目标库,包含Scala.js注释的存根注释(@JSExport
等)。
您可以将它作为“提供”依赖项添加到您的JVM项目中,因此在运行时不需要它:
libraryDependencies +=
"org.scala-js" %% "scalajs-stubs" % scalaJSVersion % "provided"
请注意,注释不是静态的,即它们甚至不会出现在.class
文件中。
有关scala-js.org的更多详情(页面底部)。