类构造函数声明......两种声明相同的方法?

时间:2012-02-16 09:46:06

标签: scala parameters constructor

我希望对此声明之间的差异进行解释:

class Clazz(param1: String, param2: Integer)

和这一个:

class Clazz(param1: String)(param2: Integer)

第二个声明是否只影响实例化对象的方式,还是有更深层次的原因我不知道。

我想到的一个原因是多个可变长度的参数,例如:

class Clazz(param1: String*)(param2: Integer*)

还有其他人吗?

2 个答案:

答案 0 :(得分:11)

#1 类型推断。它从左到右,按参数列表完成。

scala> class Foo[A](x: A, y: A => Unit)
defined class Foo

scala> new Foo(2, x => println(x))
<console>:24: error: missing parameter type
              new Foo(2, x => println(x))
                         ^

scala> class Foo[A](x: A)(y: A => Unit)
defined class Foo

scala> new Foo(2)(x => println(x))
res22: Foo[Int] = Foo@4dc1e4

#2 隐式参数列表。

scala> class Foo[A](x: A)(implicit ord: scala.Ordering[A]) {
     |   def compare(y: A) = ord.compare(x, y)
     | }
defined class Foo

scala> new Foo(3)
res23: Foo[Int] = Foo@965701

scala> res23 compare 7
res24: Int = -1

scala> new Foo(new {})
<console>:24: error: No implicit Ordering defined for java.lang.Object.
              new Foo(new {})
              ^

答案 1 :(得分:3)

在第二个版本中,您将为Clazz声明一个curried主要构造函数。因此,两个版本之间的差异与Scala中“正常”和curried函数之间的差异相同,即

def foo(param1: String, param2: Int)

def foo(param1: String)(param2: Int)

大多数情况下,这两个声明都可以互换使用,但如果你经常需要curry函数,那么以curry形式声明它更有意义。请注意,您也可以将普通函数甚至构造函数转换为curried形式,例如,您可以使用以下方法将正常的Clazz构造函数转换为curried形式:

(new Clazz(_, _)).curried

如果要传递隐式值,则还需要多个参数列表(因为关键字隐式应用于完整参数列表)