【问题标题】:understanding Scala behaviour in auxiliary constructors with a function as parameter以函数为参数理解辅助构造函数中的 Scala 行为
【发布时间】:2013-08-26 15:24:44
【问题描述】:

我一直在学习 Scala,到目前为止它一直很好,遗憾的是我发现了一些我不完全理解的行为。希望大家给点线索,我写这个类的时候就出现了问题:

class Point(iDim:Int,data:Array[Double],f: Array[Double] => Double) {
...
def this(idim: Int, obj :ObjectThatGenerate_ArrayofDouble, f: Array[Double] => Double){
  this(idim,obj.generateArray(idim),f)
}
}

所以当我在主代码中使用这些构造函数时,我需要这样做

var p:Point = new Point (idim,obj,f _)

var p:Point = new Point (idim,dataArray,f _)

但如果我删除辅助构造函数,我只需要像这样构建对象:

var p:Point = new Point (idim, dataArray, f)

为什么在scala中当我有一个辅助构造函数时我需要传递一个部分实现的函数“f _”,而当我没有一个辅助构造函数时我可以直接传递函数“f”?或字符“_ " 在这种情况下还有其他含义吗?

【问题讨论】:

  • 这看起来像是类型推断的一些不幸限制,在处理重载的构造函数时遇到了一些麻烦。

标签: scala multiple-constructors


【解决方案1】:

正如@ghik 所说,当您使用方法(或在本例中为构造函数)重载时存在类型推断限制。一般来说,你应该尽量避免重载,这几乎不是好的做法。

这里的解决方法是使用第二个参数列表,例如

trait Generator {
  def generateArray(idim: Int): Array[Double]
}

class Point(iDim: Int, data: Array[Double], f: Array[Double] => Double) {
  def this(idim: Int, gen: Generator)(f: Array[Double] => Double) {
    this(idim, gen.generateArray(idim), f)
  }
}

val obj = new Generator {
  def generateArray(idim: Int) = new Array[Double](idim)
}

def f(arr: Array[Double]) = arr.sum

new Point(33, obj)(f)

将函数参数放入第二个参数列表在 Scala 中很常见,因为它为函数文字提供了方便的语法。因为new Point(...) { ... } 将被解释为使用匿名主体扩展类,所以更好的解决方案——并摆脱重载——是使用伴生对象:

object Point {
  def apply(idim: Int, gen: Generator)(f: Array[Double] => Double) =
    new Point(idim, gen.generateArray(idim), f)
}
class Point(iDim: Int, data: Array[Double], f: Array[Double] => Double)

Point(33, obj)(f)
Point(33, obj) { arr => arr.sum / arr.size }

(注意:apply方法也可以写成一个参数列表。因为没有重载,所以不用下划线也没有问题)

【讨论】:

    猜你喜欢
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多