使用预期的类型类和子类类型参数定义函数

时间:2016-05-17 22:28:44

标签: scala

假设:

install.packages("Rmpfr" , INSTALL_opts = "--with-mpfr-include=/path/to/mpfr/include")

install.packages("Rmpfr" , configure.args = "--with-mpfr-include=/path/to/mpfr/include")

install.packages("Rmpfr" , configure.vars = "--with-mpfr-include=/path/to/mpfr/include")

和一个类型:

scala> sealed trait Father
defined trait Father

scala> case object Son extends Father
defined object Son

接下来,我定义了函数scala> trait Foo[A] defined trait Foo ,据我所知,它希望类型参数fA的子类,并且有一个类型类Father的实例。

Foo

然后,我定义了一个实例:

scala> def f[A <: Father : Foo](x: Father): String = x.toString
f: [A <: Father](x: Father)(implicit evidence$1: Foo[A])String

最后我称之为:

scala> implicit val fooFather = new Foo[Father] {}
fooFather: Foo[Father] = $anon$1@4f25b795

但是,在我看来,scala> f(Son) res0: String = Son 可以写成:

f

是否有编写上述函数def f[A <: Father](x: Father)(implicit ev: Foo[A]): String = x.toString 的首选方法?而且,它们之间有区别吗?

1 个答案:

答案 0 :(得分:3)

不,他们是完全一样的。

上下文界限,btw是Foodef f[A <: Father : Foo]被调用的方式,有一个问题。如果在方法的主体中你需要引用隐式参数,你最终需要使用implicitly[Foo[A]],这很不方便,即

def f[A <: Father : Foo](x: Father): String = {
  implicitly[Foo[A]].ifFooHadAMethod // couldn't think of a better example :)
  x.toString
}

这就是为什么在很多代码中人们使用

def f[A <: Father : Foo](x: Father)(implicit ev:Foo[A]): String = {
  ev.ifFooHadAMethod // couldn't think of a better example :)
  x.toString
}

我个人更喜欢第二种情况,只要我需要引用隐式参数,否则我更喜欢使用上下文边界。