scala - 添加伴生项目后无法直接调用使用类名映射类型
问题描述
当我们有一个案例类时,我们用类型的名称调用 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)
解决方案
如果您根本不定义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
方法的存在。
推荐阅读
- wpf - 从另一个视图模型调用函数时,RaisePropertyChanged 不更新属性
- javascript - javascript - 为带有背景的视频制作屏幕截图按钮
- php - Predis 与 laravel 5.5 “Aggregate/RedisCluster.php:337 中的池中没有可用连接”
- angular - 使用 cookie 自动登录,Angular 6
- java - 在 Azure Function 中设置许可证
- apache-kafka - 是否有从 Zookeeper/Kafka 获取 StreamsMetadata 的 API
- python - Django从第三级外键表中删除行
- r - 在添加列的同时重复数据帧 n 次
- shell - ansible playbook shell模块转义特殊字符
- html - 带有渐变的 Ionic 3 背景图像在设备中不起作用