加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 含糊的隐含值

发布时间:2020-12-16 21:33:49 所属栏目:安全 来源:网络整理
导读:一直以来,我一直在思考 scala implicits,直到最近面临着奇怪的问题. 在我的应用程序中,我有几个域类 case class Foo(baz: String)case class Bar(baz: String) 以及一个能够从字符串构造域对象的类.它可以被子类化以进行真正的反序列化,这并不重要. class Re
一直以来,我一直在思考 scala implicits,直到最近面临着奇怪的问题.

在我的应用程序中,我有几个域类

case class Foo(baz: String)
case class Bar(baz: String)

以及一个能够从字符串构造域对象的类.它可以被子类化以进行真正的反序列化,这并不重要.

class Reads[A] {
  def read(s: String): A = throw new Exception("not implemented")
}

接下来,有隐式解串器

implicit val fooReads = new Reads[Foo]
implicit val barReads = new Reads[Bar]

还有一个帮助程序将字符串转换为域类之一

def convert[A](s: String)(implicit reads: Reads[A]): A = reads.read(s)

不幸的是,试图使用它

def f(s: String): Foo = convert(s)

我得到编译器错误,像

error: ambiguous implicit values:
 both value fooReads of type => Reads[Foo]
 and value barReads of type => Reads[Bar]
 match expected type Reads[A]
       def f(s: String): Foo = convert(s)
                                      ^

对我来说,代码看起来很简单和正确.阅读[Foo]和Reads [Bar]是一个完全不同的类型,什么是含糊的?

真正的代码要复杂得多,并且使用play.api.libs.json,但这个简化版本足以复制错误.

解决方法

您在示例中遇到的歧义是您没有告诉Scalac想要使用哪一个.你需要用你的代码替换

def f(s: String): Foo = convert[Foo](s)

以确定使用哪一个.它不能从f的返回类型推断.这里需要明确.

回应评论

让我玩魔鬼的倡导者在这里.

trait Foo
case class Bar(s: String) extends Foo
case class Baz(s: String) extends Foo

def f(s: String): Foo = convert(s)

假设为Bar和Baz定义了一个隐含的,它是隐含的?我确定那里有更多恶魔的角落,但是这一次跳到我身边.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读