Scala中的分配

时间:2015-07-17 02:54:55

标签: scala

我在Scala中看到了一个奇怪的片段,我不太明白。对我来说,Scala中的赋值返回Unit,与Java不同,它返回已影响值的变量类型。但是,让我们考虑这个类:

case class C(i: Int) {
  def f = C(i = i + 10) 
}

这个编译完全没问题,这很奇怪!工厂方法C.apply需要Int,而我传递的类型为Unit的似乎是赋值。顺便说一句,如果我删除赋值只是让表达式,它似乎有完全相同的行为。

我们现在试试这个:

case class C(i: Int) {
   def f = {
     i = i + 10
     C(i = i + 10)
   }
}

好了,现在这是我所知道的世界:i是一个val,然后你不能改变它,所以i = i + 10不能编译。但是,C(i = i + 10)仍然可以编译而不会抱怨。这怪异是什么?这有什么理由存在吗?

1 个答案:

答案 0 :(得分:8)

这是因为,在C(i = i + 10)的情况下,左侧i不是字段C#i而是named parameter。根本没有任何任务。

C(i = i + 10)
  ^   ^
  +---|-------- Parameter name
      |
      +- - - - - - - - - - - - - - Reference to the field `i`
                                   in the instance of the class `C`

命名参数有意义的地方:

  • 避免"这个{boolean, integer}是什么意思"时刻:

    someMethod(anObject, flagName=true)
    // As opposed to someMethod(anObject, true) ... what's `true` for? 
    
    anotherMethod(arg1, arg2, totalMagic=33)
    
  • 使用参数的默认值(调用正确的构造函数)时:

    def withDefaults(i: Int, flag: Boolean = true, wrapper: Option[String] = None) = {
      wrapper.fold(s"$i with $flag")(_.format(i, flag))
    }
    
    withDefaults(3, Some("stuff %s around %s"))
    // won't compile
    // error: type mismatch;
    //  found   : Some[String]
    //  required: Boolean
    
    withDefaults(3, wrapper = Some("stuff %s around %s"))
    // works (returns "stuff 3 around true")