Scala中空/无/单位的用法

我刚刚阅读: http : //oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/

就我所知, Null是一个特征,它的唯一实例是null

当一个方法接受一个Null参数时,我们只能直接传递一个Null引用或null ,但不能传递任何其他引用,即使它是null(例如nullString: String = null )。

我只是想知道在哪些情况下使用这个Null特性是有用的。 还有没有什么特质,我没有看到更多的例子。


我真的不明白使用Nothing和Unit作为返回types有什么区别,因为两者都不返回任何结果,当我有一个执行日志logging的方法时,如何知道使用哪一个?


你有没有使用Unit / Null / Nothing作为返回types的东西?

如果方法永远不会返回,则只使用Nothing(意思是它不能通过返回正常完成,它可能会抛出exception)。 没有什么是不会被实例化的,并且是为了types系统的好处的(引用James Iry的话: “Scala有一个底层types的原因与它在types参数中表示差异的能力有关” )。 从您链接到的文章:

Nothing的另一个用途是作为永不返回的方法的返回types。 如果你仔细想想,这是有道理的。 如果方法的返回types是Nothing,并且绝对不存在Nothing的实例,那么这样的方法不能返回。

您的logging方法将返回单位。 有一个价值单位,所以它可以实际返回。 从API文档 :

单位是scala.AnyVal的子types。 只有一个types为Unit()的值,并且它不是由基础运行时系统中的任何对象表示的。 返回typesUnit的方法类似于声明为void的Java方法。

你引用的文章可能会引起误解。 Nulltypes与Java虚拟机兼容,尤其是Java。

我们必须考虑到斯卡拉

  • 是完全面向对象的:每个值都是一个对象
  • 是强types的:每个值都必须有一个types
  • 需要处理null引用来访问,例如Java库和代码

因此有必要为null值定义一个types,它是Null trait,并且只有null

Nulltypes中没有什么特别的用处,除非你是types系统或者你正在编译器上开发。 特别是我看不出有什么合理的理由为一个方法定义一个Nulltypes的参数,因为你不能传递任何东西而是null

你有没有使用Unit / Null / Nothing作为返回types的东西?


Unit可以这样使用:

 def execute(code: => Unit):Unit = { // do something before code // do something after } 

这允许你传入一个任意代码块来执行。


对于可为空的任何值, Null可以用作底部types。 一个例子是:

 implicit def zeroNull[B >: Null] = new Zero[B] { def apply = null } 

None的定义中None使用None

 object None extends Option[Nothing] 

这使您可以将“ None分配给任何types的Option因为Nothing “扩展”所有内容。

 val x:Option[String] = None 

我从来没有真正使用过Nulltypes,但是你使用Unit ,你会在Java上使用voidNothing是特别的types,因为正如Nathan已经提到的那样,没有Nothing是不可能的。 Nothing是所谓的bottom-type,也就是说,它是任何其他types的子types。 这个(和逆变types参数)就是为什么你可以在Nil加上任何值 – 这是一个List[Nothing] – 然后列表就是这个元素types。 也Nonetypes的Option[Nothing] 。 每次尝试访问这种容器内的值都会引发exception,因为这是从Nothingtypes的方法返回的唯一有效方法。

如果您使用Nothing ,则无需执行任何操作(包括打印控制台),如果您执行某些操作,请使用输出typesUnit

 object Run extends App { //def sayHello(): Nothing = println("hello?") def sayHello(): Unit = println("hello?") sayHello() } 

…那么如何使用Nothing

 trait Option[E] case class Some[E](value: E) extends Option[E] case object None extends Option[Nothing] 

没有什么是经常使用的。 在下面的代码中, val b: Boolean = if (1 > 2) false else throw new RuntimeException("error") else子句的types为Nothing ,它是Boolean的子类(以及其他任何AnyVal)。 因此,整个赋值对编译器是有效的,尽pipeelse子句并没有真正返回任何东西。