为什么更喜欢隐式Val而不是隐式对象 [英] Why prefer implicit val over implicit object

查看:58
本文介绍了为什么更喜欢隐式Val而不是隐式对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在询问有关隐式的问题时,与答案(有时甚至是答案本身)一起给出的常见建议/建议/建议是使用隐式值带有明确类型签名,而不是使用隐式对象.

When asking questions about implicits a common suggestion / recommendation / advice that is given together with the answer (or sometimes that is the answer itself) is to use implicit vals with excplicit type signatures instead of using implicit objects.

但是,其背后的原因是什么?

But, what is the reason behind that?

推荐答案

"TL; DR;" 原因是具有明确类型的隐式val 签名具有所需的确切类型,而隐式对象具有不同的类型.

"TL;DR;" The reason is that an implici val with an explicit type signature has the exact type you want whereas an implicit object has a different type.

显示一个为什么可能是问题的最好方法是一个简单的示例:

The best way to show why that could be a problem is with a simple example:

// Having the following definitions.

trait SomeTrait[T] {
  def f: T
}

trait ExtendedTrait[T] extends SomeTrait[T] {
  def g: T
}

implicit val SomeStringVal: SomeTrait[String] = new SomeTrait[String] {
  override def f: String = "from val f"
}

implicit val ExtendedStringVal: ExtendedTrait[String] = new ExtendedTrait[String] {
  override def f: String = "from extended val f"
  override def g: String = "from extended val g"
}

implicit object ExtendedStringObject extends ExtendedTrait[String] {
  override def f: String = "from extended obj f"
  override def g: String = "from extended obj g"
}

// What will be the result of:
implicitly[SomeTrait[String]].f

请记住:

如果有多个与隐式参数类型匹配的合格参数,则将使用静态重载解析规则选择最具体的参数.

If there are several eligible arguments which match the implicit parameter's type, the most specific one will be chosen using the rules of static overloading resolution.

那么,答案是:来自扩展obj f" .
上面的(有点令人惊讶)结果是由于对象具有自己的类型(单个类型 ExtendedStringObject.type ,它是 ExtendedTrait [String]的子类型)而导致的.] ),因此,它比其他类型更特定" .

Well then, the answer is: "from extended obj f".
The above (somewhat surprising) result, is caused because objects have their own type (singleton type ExtendedStringObject.type which is a subtype of ExtendedTrait[String]), as such, it is more "specific" than the others.

现在,这可能是一个问题,原因是大多数人都不知道 object 具有其自身的类型,并且它比他们所相信的更具体.但是,这也可能使您在不想使用 object 时可以选择它.例如:

Now, the reason why that could be a problem is that most people are not aware that the object has its own type and that it is more specific than what they believe. Nevertheless, this could also make the object to be picked when you would not want it to be; for example:

// If instead we only had this:

implicit val ExtendedStringVal: ExtendedTrait[String] = new ExtendedTrait[String] {
  override def f: String = "from extended val f"
  override def g: String = "from extended val g"
}

implicit object ExtendedStringObject extends SomeTrait[String] {
  override def f: String = "from extended obj f"
}

// Then what will be the result of:
implicitly[SomeTrait[String]].f

在这种情况下,我们将有一个模糊隐含值" 异常;因为这两个选项都是特定的.

In this case, we will have an "ambiguous implicit values" exception; because both options are equally specific.

否.

与软件工程中的大多数事情一样,没有什么是普遍的.
在某些情况下,使用带有显式类型签名的隐式val 要么 (例如,因为即使编译器知道该类型,该类型也无法在源代码中写入)

As with most things in software engineering, nothing is universal.
There are cases where using an implicit val with an explicit type signature is either not possible (for example, because the type is not writable in source code even if the compiler knows it exists) or it would not produce the correct result whereas an implicit object would do.
A simple example would be:

trait A {
  type X
}

object A {
  type Aux[XX] = A { type X = XX }
}

class B extends A {
  type X = T

  class T
}

implicit object b extends B
implicit object b1 extends B

这样您可以隐式请求[code.A.Aux [bT]] ,而使用隐式val b:B =新的B {} 是行不通的.br/>(运行代码此处完整上下文

Such that you can ask for implicitly[A.Aux[b.T]] whereas using implicit val b: B = new B {} would have not worked.
(code running here full context here).

但是,可以说这些是罕见的(高级)案例.因此,这可以被认为是一个很好的指南.

However, it could be said that those are rare (advanced) cases. As such, this could be considered a good guideline.

这篇关于为什么更喜欢隐式Val而不是隐式对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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