隐式值的隐式转换可以满足隐式参数吗? [英] Can an implicit conversion of an implicit value satisfy an implicit parameter?

查看:91
本文介绍了隐式值的隐式转换可以满足隐式参数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在定义一些Scala隐式对象,以使处理一组特定的不可更改的Java类更加容易.以下Scala代码是一个简化的示例,显然看起来很疯狂,在现实世界中,我试图从Monkey,Tree&隐式地获取特定资源(而不是数字年龄).鸭,可用于各种方法,例如purchaseCandles():

I'm defining some Scala implicits to make working with a particular unchangeable set of Java classes easier. The following Scala code is a simplified example that obviously looks crazy, in the real world I'm trying to grab particular resources (rather than numeric age) implicitly from the Monkey, Tree & Duck for use in various methods like purchaseCandles():

// 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次:

The compiler error, which occurs 3 times:

could not find implicit value for parameter age: Int 
purchaseCandles()
               ^

撇开该示例代码的疯狂之处,有很多不同的方法,我真正的问题是:隐式值的隐式转换能否满足Scala中的隐式参数?

Leaving aside the many different ways in which this sample code is crazy, my real question is: can implicit conversions of implicit values satisfy implicit parameters in Scala?

推荐答案

简短答案:否. Scala的编译器只会使用单个隐式,因此如果无法发现implicit int,它将停止并放弃.

Short answer: no. Scala's compiler will only ever look to apply a single implicit, so if it fails to spot an implicit int lying around, it will stop and give up.

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

However, you could write your purchaseCandles method to operate on types that can be converted to an Int, and require a parameter of that type:

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

asAge部分对于强制应用隐式转换是必需的.

The asAge part is necessary to force the application of the implicit conversion.

到目前为止,在这种情况下,我似乎需要指定A的类型,尽管我无法弄清楚原因:因为类型周围不应存在其他可以隐式转换为<的值c3>(这种情况也发生在全新类型上,因此它不是Int的普遍存在.)但是您可以这样做:

As of yet, I seem to need to specify the type of A in this scenario, though I can't work out why: since there shouldn't be other values around of types that can be implicitly converted to Int (this happens with brand new types as well, so it's not the ubiquity of Int.) But you can do:

{
  implicit val guest = Monkey(10000)

  purchaseCandles[Monkey]()
}

但是,使用隐式可能不是一个好主意!

This use of implicits, however, is probably a bad idea!

这篇关于隐式值的隐式转换可以满足隐式参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆