首页 > 解决方案 > 添加伴生项目后无法直接调用使用类名映射类型

问题描述

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

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: 错误:类型不匹配;
找到:ScalaFiddle.this.Foo.type
需要:scala.this.Function1[lang.this.String,?]
val foo = value.map(Foo)

标签: scalatraitscompanion-object

解决方案


如果您根本不定义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

它不再extend是 s 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方法的存在。


推荐阅读