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

Scala解析多个隐式参数

发布时间:2020-12-16 19:25:11 所属栏目:安全 来源:网络整理
导读:在尝试回答 this question时,我想出了以下代码: case class Monkey(bananas: Int) case class Tree(rings: Int) case class Duck(quacks: Seq[String]) implicit class IntLike(val x : Int) extends AnyVal implicit def monkey2Age(monkey: Monkey): IntL
在尝试回答 this question时,我想出了以下代码:

case class Monkey(bananas: Int) 
    case class Tree(rings: Int)
    case class Duck(quacks: Seq[String])

    implicit class IntLike(val x : Int) extends AnyVal

    implicit def monkey2Age(monkey: Monkey): IntLike = monkey.bananas / 1000
    implicit def tree2Age(tree: Tree): IntLike = tree.rings
    implicit def duck2Age(duck: Duck): IntLike = duck.quacks.size / 100000

    def purchaseCandles[A <% IntLike]()(implicit age : A) = {
      val asAge : IntLike = age
      println(s"I'm going to buy $asAge candles!")
    }              

    {
        implicit val guest = Tree(50)
        purchaseCandles()
    }

请注意,IntLike只是为了让我相信这不是一个专注于Int的问题.

这似乎是一个相当标准,如果不好,使用implicits,我期待它愉快地工作.但是,在调用purchaseCandles()时,REPL会产生以下错误:

error: ambiguous implicit values:
both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String]
and value guest of type Tree
match expected type A

我不能为我的生活看到这是怎么回事. A必然会有一个IntLike的视图边界,这是我刚刚发明的一种类型. REPL确认没有可用的隐式视图:

scala> implicitly[Tree => IntLike]

res14: Tree => IntLike = function1

scala> implicitly[scala.collection.generic.CanBuildFrom[String,String] => IntLike]

:18: error: No implicit view available from scala.collection.generic.CanBuildFrom[String,String] => IntLike.

那么StringCanBuildFrom如何成为合适的类型呢?编译器是否能够解析多个依赖的implicits,如果没有,为什么会显示错误?

解决方法

在尝试回答之前,首先是减少的案例.请注意,您正在调用purchaseCandles而没有任何关于类型A的提示,我认为这是问题的根源.

object Foo

def test[A <% Foo.type](implicit bar: A) {}

test

错误:

<console>:10: error: ambiguous implicit values:
 both value StringCanBuildFrom in object Predef of type =>
     scala.collection.generic.CanBuildFrom[String,String]
 and method conforms in object Predef of type [A]=> <:<[A,A]
 match expected type A
              test
              ^

StringCanBuildFrom看起来更像一个令人困惑的错误消息.如果你专注于conforms,那么这个不起作用的原因可能会变得更加明确:Predef.conform声明无论何时你要求隐式转换A => A,这是通过身份保证的.这样,如果你有def foo [B<%A](b:B),你总是可以用类型A的值调用foo,而不需要定义任何类型的A =>一个.

您要求解析未指定类型的隐式参数以及从未指定类型到IntLike的转换.我认为这超出了隐式分辨率算法的范围.仍然错误消息有点奇怪.

(编辑:李大同)

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

    推荐文章
      热点阅读