我是Scala的新手并尝试使用以下继承:
abstract class Command(arg: Any)
case object Help extends Command // <---- Ok
但如果我用这个替换它:
abstract class Command(arg: Option[Any])
case object Help extends Command // <---- Fail
为什么呢?为什么它在第一个例子中起作用?
答案 0 :(得分:5)
第一种情况被编译器接受,因为它将构造函数参数调整为()
,即Unit
类型的单个实例:
$ scala -Xlint:adapted-args
Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.
scala> abstract class Command(arg: Any)
defined class Command
scala> case object Help extends Command
<console>:12: warning: Adaptation of argument list by inserting () is deprecated: leaky (Object-receiving) target makes this especially dangerous.
signature: Command(arg: Any): Command
given arguments: <none>
after adaptation: new Command((): Unit)
case object Help extends Command
^
defined object Help
如您所见,这一行:
case object Help extends Command
已被编译器重写为:
case object Help extends Command(())
也就是说,它将()
作为构造函数参数传递,这很好,因为参数的类型为Any
,而Unit
满足该约束。
但是,在第二种情况下,构造函数参数的类型为Option
,而Unit
将不满足该约束,因此编译器无法神奇地填充构造函数参数。
在任何情况下,最好使用scalac选项-Yno-adapted-args
完全禁用此魔术行为。