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方法。
你引用的文章可能会引起误解。 Null
types与Java虚拟机兼容,尤其是Java。
我们必须考虑到斯卡拉 :
- 是完全面向对象的:每个值都是一个对象
- 是强types的:每个值都必须有一个types
- 需要处理
null
引用来访问,例如Java库和代码
因此有必要为null
值定义一个types,它是Null
trait,并且只有null
。
在Null
types中没有什么特别的用处,除非你是types系统或者你正在编译器上开发。 特别是我看不出有什么合理的理由为一个方法定义一个Null
types的参数,因为你不能传递任何东西而是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
我从来没有真正使用过Null
types,但是你使用Unit
,你会在Java上使用void
。 Nothing
是特别的types,因为正如Nathan已经提到的那样,没有Nothing
是不可能的。 Nothing
是所谓的bottom-type,也就是说,它是任何其他types的子types。 这个(和逆变types参数)就是为什么你可以在Nil
加上任何值 – 这是一个List[Nothing]
– 然后列表就是这个元素types。 也None
types的Option[Nothing]
。 每次尝试访问这种容器内的值都会引发exception,因为这是从Nothing
types的方法返回的唯一有效方法。
如果您使用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子句并没有真正返回任何东西。