添加伴生项目后不能直接调用use class name to map type

Cannot call use class name directly to map type after adding a companion project

当我们有一个案例class时,我们用类型的名称调用映射类型,例如:

case class Foo(value: String)
val value = Some("Yay!")
val foo = value.map(Foo)

但是如果我们还提供一个伴生对象,它就停止工作 value.map(Foo) 并且看起来像这样工作:value.map(Foo(_))。为什么?

case class Foo(value: String)
object Foo {}
val value = Some("Yay!")
val foo = value.map(Foo)
println(foo)

ScalaFiddle.scala:5: error: type mismatch;
found : ScalaFiddle.this.Foo.type
required: scala.this.Function1[lang.this.String,?]
val foo = value.map(Foo)

如果您根本不定义 object Foo,则合成伴随对象具有以下声明:

<synthetic> object Foo 
   extends scala.runtime.AbstractFunction1[String,Foo] 
      with Serializable

但是如果你自己定义object Foo如下

case class Foo(v: String)
object Foo {}

然后 Foo 对象的声明相应更改为:

object Foo extends scala.AnyRef with Serializable

它不再是 extends Function1

方法apply(v: String): Foo仍然在Foo上自动生成,但它不再实现Function1[String, Foo]接口。如果你像这样声明伴生对象:

object Foo extends (String => Foo) { ... }

然后您可以再次在 value.map(Foo).

等表达式中使用它

value.map(Foo(_)) 语法总是有效,因为它只是

的快捷方式
value.map(x => Foo.apply(x))

而闭包根本不关心Foo实现了哪些接口,它只关心apply方法是否存在。