为什么在Scala中定义方法时会添加“:Unit =”?

时间:2018-04-04 09:21:58

标签: scala intellij-idea

伙计我正在尝试学习Scala,我使用IntelliJ IDEA来实现它,事情是我在互联网上看到一个代码定义如下的代码:

def move(dx: Int, dy: Int, dz: Int) {}

但是当我尝试在IntelliJ IDEA中定义方法时,它会在大括号之前自动添加:“Unit =”而我不知道这意味着什么?像这样:

 def move(dx: Int, dy: Int, dz: Int): Unit ={}

谢谢你的帮助

6 个答案:

答案 0 :(得分:4)

程序语法

def methodName(arg1: Type1, ..., argN: TypeN) {
  /* method body */
}

仅仅是返回类型为Unit的方法的语法糖。它相当于

def methodName(arg1: Type1, ..., argN: TypeN): Unit = {
  /* method body */
}

类型Unit包含单个值:空元组()。因此,除非方法通过抛出异常或错误而异常退出,否则它将返回nullary元组()。这反过来意味着方法的返回值并不重要,因为除了方法终止之外,它不包含任何有意义的信息。因此,它通常用于仅为其副作用而执行的方法。

正如EmreSevinç正确指出的那样,不再使用过程语法,它可以帮助您避免键入六个字符,但会使语法整体上不那么一致,所以它并不值得。

这不是一个答案,更多的是尝试解决有关Unitvoid的混淆。

虽然乍一看Unit似乎在void这样的语言中使用了C,但实际上却完全不同,因为Unit实际上是void确实有一个值,而C中的Unit类似的语言通常(令人困惑)没有List( (), (), (), (), () ) 类型的值。这使得从List[Unit]构造更复杂的值成为可能。例如,

Left( () ); Right( () )

Either[Unit, Unit]类型的值,可以表示自然数。同样,

()

map类型的值,可以表示布尔值。这两个例子显然是人为的。 “Scala中的函数式编程”(P. Chiusano,R。Bjarnason)提供了一个更实质和实用的例子,map2Applicative[F[_]]中从def map[B](fa: F[A])(f: A => B): F[B] = map2(fa, point( () ))((a, _) => f(a)) // ^ // | // Here is it 派生()时派上用​​场{1}}类型类:

Unit

(如果没有上下文,这应该是不可理解的:我只是想提供一个具体的例子,this可以用来在非常一般的框架中定义非常基本的方法)

从高级别的角度来看,语言中的//declaring OnClickListener as an object private OnClickListener btnClick = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }; //passing listener object to button btn1.setOnClickListener(btnClick); 类型是 Really Good Thing ,因为它使类型和函数的类别cartesian closed (它是定义第一部分的“终端对象”)。这使得语言整体上更加一致和对称。

答案 1 :(得分:3)

根据Scala Style Guide's procedure syntax

  

避免使用过程语法,因为它往往会让人感到困惑   收获很少。

// don't do this
def printBar(bar: Baz) {
  println(bar)
}

// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}

答案 2 :(得分:1)

首先,我要感谢大家帮助我!

我在本教程中找到了这个:https://docs.scala-lang.org/tour/basics.html

“方法greet的返回类型是Unit,它表示返回没有任何意义。它与Java和C中的void类似地使用。(不同之处在于因为每个Scala表达式都必须有一些值,实际上有一个单词类型Unit的单例值,write()。它不携带任何信息。)“

我相信总结一下@AndreyTyukin在他的解释中所说的。

答案 3 :(得分:0)

这通常是为公共方法添加的,因为IntelliJ希望它们具有显式类型签名。

通常,最佳做法是添加这些类型的签名,但如果将其删除则会自动推断。它非常明确地表示函数不返回任何内容。这意味着它有副作用(或者首先是无用的);)

def foo(){}只是语法糖,人们可以争论它是否真的合理存在。

答案 4 :(得分:0)

如果您熟悉编程语言," Unit"意味着" Void"。所以"单位"表示该函数不返回任何值,例如Int,布尔...

":单位="可以是可选的,取决于上下文,这就是为什么有时候你会看到它或没有它的功能。

答案 5 :(得分:0)

原因是IntellJ有时会有助于拥有更好的编码风格。例如,如果没有为方法定义返回类型(使用def定义),则IntellJ提供返回类型。这是因为最好有一个清晰的方法签名(签名由名称,输入参数,正文及其类型和返回类型组成)。另请注意,Scala也是一种函数式编程语言,也是面向对象的。所以类型非常重要,因此是编码风格的一部分。

这里有一条建议;每当您不确定底层库时,请使用hold ctrl键并单击它。例如,如果我点击Unit,我将获得以下内容:

/** `Unit` is a subtype of [[scala.AnyVal]]. There is only one value of type
 *  `Unit`, `()`, and it is not represented by any object in the underlying
 *  runtime system. A method with return type `Unit` is analogous to a Java
 *  method which is declared `void`.
 */