Scala中的递增(++)运算符

ade*_*rsq 56 scala increment

Scala是否有任何理由不支持++运算符默认增加基本类型?例如,你不能写:

var i=0
i++
Run Code Online (Sandbox Code Playgroud)

谢谢

pka*_*ing 36

我猜这是省略的,因为它只适用于可变变量,对于不可变值没有意义.也许决定++操作员不会尖叫分配,因此包含它可能会导致错误,无论您是否正在改变变量.

我觉得这样的事情是安全的(在一条线上):

i++
Run Code Online (Sandbox Code Playgroud)

但这是一种不好的做法(用任何语言):

var x = i++
Run Code Online (Sandbox Code Playgroud)

您不希望混合赋值语句和副作用/变异.

  • 我想你不是C/C++的忠实粉丝.各种各样的`*(a ++)= ++*(b ++)`东西...... (29认同)
  • 我是C++首席开发人员:如果我可以提供帮助,我的代码库中没有任何废话. (15认同)
  • @Rex Kerr:现在我觉得我的第一个编程语言是Java :) (3认同)

Dan*_*ral 33

我喜欢克雷格回答,但我认为必须更加强烈.

  1. 没有"原语" - 如果Int可以做到,那么用户自己也可以Complex(例如).

  2. 基本用法++是这样的:

    var x = 1 // or Complex(1, 0)

    x++

  3. 你怎么++在课堂上实现Complex?假设,Int对象是不可变的,那么该++方法需要返回一个对象,但必须分配该新对象.

这需要一种新的语言功能.例如,假设我们创建了一个assign关键字.类型签名也需要更改,以指示++返回 a Complex,但分配给持有当前对象的任何字段.在Scala没有干扰程序员命名空间的精神中,让我们说我们通过在类型前加上来做到这一点@.

然后它可能是这样的:

case class Complex(real: Double = 0, imaginary: Double = 0) {
  def ++: @Complex = {
    assign copy(real = real + 1)
    // instead of return copy(real = real + 1)
}
Run Code Online (Sandbox Code Playgroud)

下一个问题是后缀运算符使用Scala规则.例如:

def inc(x: Int) = {
  x++
  x
}
Run Code Online (Sandbox Code Playgroud)

由于Scala规则,这与以下内容相同:

def inc(x: Int) = { x ++ x }
Run Code Online (Sandbox Code Playgroud)

这不是意图.现在,Scala拥有流畅的风格:obj method param method param method param ....这很好地融合了C++/Java传统语法object method parameter和函数编程概念,通过多个函数来管道输入以获得最终结果.这种风格最近也被称为"流畅的界面".

问题在于,通过对该样式进行特权保护,它会削弱后缀运算符(并且前缀为1,但Scala几乎没有它们).因此,在最后,斯卡拉将不得不作出大的变化,这将能够测量到C/Java的增量和减量运算的风采呢-除非它真的从那种事也离开支持.


Cra*_*lin 20

在Scala中,++是一种有效的方法,没有方法意味着赋值.只能=这样做.

更长的答案是像C++和Java这样的语言++特别对待,Scala =特别对待,并且以不一致的方式对待.

在编写Scala时i += 1,编译器首先查找+=在Int上调用的方法.它不存在,所以接下来就是它的神奇之处=并尝试编译该行,就像它读取一样i = i + 1.如果你写i++那么斯卡拉将调用方法++i和结果分配给什么都没有.因为只=意味着分配.你可以写,i ++= 1但那种方式会失败.

Scala支持方法名称的事实+=已经引起争议,有些人认为它是运算符重载.他们可能已经添加了特殊行为,++但它不再是一个有效的方法名称(如=),这将是另一件需要记住的事情.


Rex*_*err 12

我认为部分原因+=1是只有一个字符,并且++在集合代码中用得很多,用于连接.所以它使代码更清洁.

此外,Scala鼓励不可变变量,并且++本质上是一个变异操作.如果您需要+=,至少可以强制所有突变通过一个共同的分配程序(例如def a_=).