【问题标题】:Scala function arguments: class vs function generic type, e.g. f(classOf[Foo], "bar") vs f[Foo]("bar")Scala 函数参数:类与函数泛型类型,例如f(classOf[Foo], "bar") 与 f[Foo]("bar")
【发布时间】:2016-07-08 15:50:11
【问题描述】:

在 Scala 中,通常的做法是将类类型作为泛型传入还是显式传入?

例如,我创建了一个辅助函数来创建一个 Java 对象,该对象接受源异常、目标异常和第三个参数(在此示例中我将只使用一个字符串)。在 Scala 中哪一个是更好的实践:

exceptionTranslation(classOf[FooException], classOf[BarException], "blah")

def exceptionTranslation(sourceClazz: Class[_ <: Throwable], targetClazz: Class[_ <: Throwable], message: String) = new Translation()
  .withSource(sourceClazz)
  .withTarget(targetClazz)
  .withMessage(message)

或者

exceptionTranslation[FooException, BarException]("blah")

def exceptionTranslation[Source <: Throwable, Target <: Throwable](message: String)(
implicit source: ClassTag[Source], target: ClassTag[Target]) = new Translation()
  .withSource(source.runtimeClass.asInstanceOf[Class[Source]])
  .withTarget(target.runtimeClass.asInstanceOf[Class[Target]])
  .withMessage(message)

【问题讨论】:

  • 我更喜欢第一个,因为您不需要任何隐式和运行时强制转换,但这是一个偏好问题。
  • 同意@Tuval,第二个绝对是矫枉过正

标签: scala class generics implicit


【解决方案1】:

我认为只是风格问题。他们都是正确的。就个人而言,我会选择更直观、更短且功能最少的那个。

类文本名称提取示例:

import scala.reflect._
def bar[F](x: Class[F]) = x.getName

def foo[X:ClassTag] = implicitly[ClassTag[X]].runtimeClass.getName

def foobar[X](implicit ctag: ClassTag[X]) = ctag.runtimeClass.getName

用法:

> bar(classOf[Double]) // This one has better Java interop 
res: String = "double"

> foo[Double]  // This looks slightly less verbose when calling 
res: String = "double"

> foobar[Double]
res: String = "double"

【讨论】:

  • 该函数是私有的,对我来说,使用函数的泛型类型来传递参数感觉很奇怪,但是在调用函数时它读起来更清晰(“foo”或“foobar”方式)。由于大多数人会阅读异常翻译列表而从不真正查看私有辅助函数,因此我认为简化对函数的调用更为重要。
猜你喜欢
  • 2015-02-21
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
相关资源
最近更新 更多