我有一个扩展App的应用程序和一个实现选项解析器的特性。所有特征需求都是运行时混合中的某些类或特征提供:
val args: Array[String]
如果我宣布:
trait OptionParser extends App {...}
一切都很好,但排除了选项解析器的任何其他用途,而不是App对象。不确定应用程序扩展App以及混合使用OptionParser是否效率低下:
object MyApp extends App with OptionParser {...}
我意识到这可以缩短为:
object MyApp extends OptionParser {...}
但理想情况下,我希望OptionParser完全独立,除非依赖args
提供,这只是因为这是App放置它们的地方。
是否有某种方法可以声明依赖项而不提供类或特征来从中获取它?可以在链接时检测到错误,以免破坏类型安全。
答案 0 :(得分:6)
不确定我到底知道你要做什么。怎么样:
trait OptionParser {
protected def args: Array[String]
}
这样,您可以将OptionParser
与提供args
的任何内容混合,而不一定是App
。
修改:由于App
将args
可见性定义为protected
,您也需要在OptionParser
中执行此操作。这很不幸。这是另一个想法:
trait OptionParser {def options: Array[String] ... }
对象MyApp使用OptionParser {def options = args ...}
扩展App答案 1 :(得分:2)
您可以在OptionParser
上使用自我类型声明执行此操作。这将要求在OptionParser
中混合的类型为App
,而不会混入App
本身。
trait OptionParser { this: App =>
def test(): Unit = {
println("test")
println(args)
}
}
object Test extends App with OptionParser {
test()
println("done")
}