首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >隐式值的隐式转换可以满足隐式参数吗?

隐式值的隐式转换可以满足隐式参数吗?
EN

Stack Overflow用户
提问于 2013-03-15 19:30:36
回答 2查看 361关注 0票数 1

我正在定义一些Scala隐式表达式,以使使用一组特定的不可更改的Java类变得更容易。下面的Scala代码是一个明显看起来很疯狂的简化示例,在现实世界中,我试图隐式地从猴子、树和鸭子中获取特定的资源(而不是数字年龄),以便在purchaseCandles()等各种方法中使用

代码语言:javascript
复制
// actually 3 Java classes I can not change:
case class Monkey(bananas: Int) 
case class Tree(rings: Int)
case class Duck(quacks: Seq[String])

// implicits I created to make my life easier...
implicit def monkey2Age(monkey: Monkey): Int = monkey.bananas / 1000
implicit def tree2Age(tree: Tree): Int = tree.rings
implicit def duck2Age(duck: Duck): Int = duck.quacks.size / 100000

// one of several helper methods that I would like to define only once,
// only useful if they can use an implicit parameter.
def purchaseCandles()(implicit age: Int) = {
  println(s"I'm going to buy $age candles!")
}

// examples of usage
{
  implicit val guest = Monkey(10000)

  purchaseCandles()
}

{
  implicit val guest = Tree(50)

  purchaseCandles()
}

{
  implicit val guest = Duck(Seq("quack", "quack", "quack"))

  purchaseCandles()
}

编译器错误,出现3次:

代码语言:javascript
复制
could not find implicit value for parameter age: Int 
purchaseCandles()
               ^

抛开这个示例代码疯狂的许多不同方面不谈,我真正的问题是:隐式值的隐式转换能否满足Scala中的隐式参数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-15 19:37:11

简短的回答是:不。Scala的编译器只会寻找应用一个隐式函数,所以如果它找不到周围的implicit int,它就会停止并放弃。

但是,您可以编写purchaseCandles方法来操作可以转换为Int的类型,并且需要该类型的参数:

代码语言:javascript
复制
def purchaseCandles[A <% Int]()(implicit age : A) = {
  val asAge : Int = age
  println(s"I'm going to buy $asAge candles!")
}

asAge部分是强制应用隐式转换所必需的。

到目前为止,我似乎需要在这个场景中指定A的类型,尽管我不知道为什么:因为在可以隐式转换为Int的类型周围不应该有其他值(这种情况在全新的类型中也会发生,所以它不是Int的普遍存在)。但是你可以这样做:

代码语言:javascript
复制
{
  implicit val guest = Monkey(10000)

  purchaseCandles[Monkey]()
}

然而,这种隐含的用法可能不是一个好主意!

票数 5
EN

Stack Overflow用户

发布于 2014-12-12 07:26:47

您实际上可以这样做:您只需将隐式转换的参数也标记为隐式:

代码语言:javascript
复制
implicit def monkey2Age(implicit monkey: Monkey): Int = monkey.bananas / 1000
implicit def tree2Age(implicit tree: Tree): Int = tree.rings
implicit def duck2Age(implicit duck: Duck): Int = duck.quacks.size / 100000

这将以你想要的方式链接它们。

一如既往:当心,它也会在你不想要的地方这样做。顺便说一句,我强烈建议不要使用Int类型的隐式参数(或其隐式值)。它太普通了。(我在某种程度上假设这就是您的示例中的情况)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15431278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档