【问题标题】:Scala type of statements?Scala 类型的语句?
【发布时间】:2020-09-22 04:40:25
【问题描述】:

我认为 Scala 将语句分类为 Unit 类型。但是当我运行以下代码时:

object HelloWorld {
  var ball = new Ball

  def main(args: Array[String]): Unit = {
    println((ball.color = "green").getClass)
  }
}

class Ball {
  var color: String = "blue"
}

输出是

void

我了解到 void 仅在 Scala 中用于与 Java 兼容。那么为什么这里用void作为这个语句的类型而不是Unit呢?

【问题讨论】:

  • 澄清一点:在 Scala 中,ball.color = "green" 是一个表达式。它可以用作语句,但在(ball.color = "green").getClass 中不是;只有整个 println(...) 是这里的声明。如果您尝试使用不能成为表达的语句,例如(var ball = new Ball).getClass(),你会看到你不能在语句上调用方法,而且它们没有类型。
  • @AlexeyRomanov 顺便说一下{var ball = new Ball}.getClass() 将是void。但是{var ball = new Ball}实际上是{var ball = new Ball; ()}

标签: java scala class types


【解决方案1】:

getClass 来自 Java。如果您在 IDE 中跳转到 getClass 的定义,您将到达 java.lang.Object#getClass

public final native Class<?> getClass();

如果你使用 Scala reflection,你会看到类型是 Unit

//libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.reflect.runtime.universe._
def getType[T: TypeTag](t: T): Type = typeOf[T]

getType(ball.color = "green") // Unit
值的

类型是不同的概念。

https://typelevel.org/blog/2017/02/13/more-types-than-classes.html

【讨论】:

    【解决方案2】:

    编译时类型的赋值表达式是Unit

    val x: Unit = (ball.color = "green")
    

    而对应的runtime类的字符串表示为void

    ().getClass
    // res1: Class[Unit] = void
    

    我猜赋值被认为是side-effect,副作用用Unit 类型表示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2022-08-17
      • 1970-01-01
      • 2019-07-09
      相关资源
      最近更新 更多