有没有办法在Scala中将默认值设置为泛型类型变量?

时间:2015-03-23 00:27:24

标签: scala

我想将默认值设置为变量。但我的Scala编译器说:

Error:(20, 16) unbound placeholder parameter
    val p: T = _
               ^

这是代码。

object InverseFunctionsExample extends App {

  type D = Double

  def f(x: D): D = 5 * x + 10
  def g(x: D): D = 0.2 * x - 2

  printMessage(isInversible(f, g))

  def printMessage(inv: Boolean): Unit = {
    if (inv) print("YES!") else print("NOPE!")
  }

  def isInversible[T](f: (T) => T, g: (T) => T): Boolean = {
    val p: T = _
    if (f(p) == g(p))
      true
    else
      false
  }
}

是否可以以某种方式初始化具有默认值的val p

3 个答案:

答案 0 :(得分:3)

只能以这种方式初始化var个字段(不是局部变量)。如果你想定义"默认值"对于不同类型,标准方法是the type-class pattern

case class Default[T](value: T)

object Default {
  implicit val defaultInt: Default[Int] = Default(0)
  implicit val defaultString: Default[String] = Default("")
  ...
}

def isInversible[T](f: (T) => T, g: (T) => T)(implicit d: Default[T]): Boolean = {
  if (f(d.value) == g(d.value))
    true
  else
    false
  // or just f(d.value) == g(d.value)
}

答案 1 :(得分:1)

您可以使用反射来实例化类的新实例,但这可能不会对您有用:

class Foo
classOf[Foo].getConstructor().newInstance()

您可以阅读有关反射API的信息,了解如何选择合适的构造函数here

您还可以使用一个参数来指定如何实例化新实例:

def isInversible[T](f: T => T, g: T => T, def: => T) = f(def) == g(def)

由于这看起来像是一个固有的数学导向问题,您可能会对Numeric类型感兴趣,这有助于为不同的数字类型提供这种逻辑。例如:

def intersectAtOrigin[T](f: T => T, g: T => T)(implicit n: Numeric[T]) = {
    val zero = n.zero
    f(zero) == g(zero)
}

然后你可以这样做:

def f(x: D): D = 5 * x + 10
def g(x: D): D = 0.2 * x - 2
intersectAtOrigin(f, g) //false, working with Doubles
intersectAtOrigin[Int](_ + 1, x => x * x + x + 1) //true, working with Ints

您可以在文档here中详细了解Numeric

答案 2 :(得分:0)

您可以将值作为T

类型的参数传递
def isInversible[T](f: (T) => T, g: (T) => T)(p: T): Boolean = {

    if (f(p) == g(p))
      true
    else
      false
  }

示例 printMessage(isInversible(f,g)(10))