Scala';空';是否算作其他类型的实例?
我有以下代码:Scala';空';是否算作其他类型的实例?,scala,types,parameters,Scala,Types,Parameters,我有以下代码: class MyLinkedList[T](h: T, tail: MyLinkedList[T]) { def prepend(v: T): MyLinkedList[T] = new MyLinkedList(v, this) } 我想知道为什么我可以将第二个参数作为null传递,并且它可以工作: val l: MyLinkedList[Int] = new MyLinkedList(1, null) null是MyLinkedList[Int]的实例吗??似乎
class MyLinkedList[T](h: T, tail: MyLinkedList[T]) {
def prepend(v: T): MyLinkedList[T] = new MyLinkedList(v, this)
}
我想知道为什么我可以将第二个参数作为null传递,并且它可以工作:
val l: MyLinkedList[Int] = new MyLinkedList(1, null)
null
是MyLinkedList[Int]的实例吗??似乎没有:
println(null.isInstanceOf[MyLinkedList[Int]])
输出false
那么原因是什么呢?
null
是Scala支持的与JVM和.NET framework上运行的其他语言反向兼容的东西。语言设计者对此并不特别兴奋,但的确,它的编译方式与Java代码一样。在本机Scala情况下不应使用它。Scala以最惯用的方式提供了备选方案,例如带有实例的Option
,Some
和None
,它们本质上是一个可空的
包装器,用于您确实需要允许空选项的时候。看看这个
class A
println(null.isInstanceOf[A]) // false
虽然我不知道为什么,但似乎isInstanceOf
在null
上没有像我们预期的那样工作。进行类型检查的另一种方法是
null: MyLinkedList[Int]
这很有效。很好地解释了Scala中的null
(以及,和):
Null
是一种特征,它(如果您不熟悉特征的话)有点像Java中的抽象类。只有一个Null
实例,即Null
。没那么难。文本null
的作用与Java中的相同。它是不引用任何对象的引用的值。因此,如果您编写的方法接受类型为Null
的参数,则只能传入两件事:Null
本身或类型为Null
的引用
因此,null
不是Scala类型系统中除null
以外的任何类型的实例:
scala> null.isInstanceOf[Any]
res1: Boolean = false
好的,那么它一定是Null
的一个实例,对吗?嗯
scala> null.isInstanceOf[Null]
<console>:8: error: type Null cannot be used in a type pattern or isInstanceOf test
null.isInstanceOf[Null]
scala>null.isInstanceOf[null]
:8:错误:类型Null不能用于类型模式或isInstanceOf测试
null.isInstanceOf[null]
总的来说,正如其他人所指出的,
Null
和Null
的存在仅仅是为了向后兼容Java。否则,Null
与Nothing
处于相同的状态,但后者没有实例,并且它是Scala类型系统的一个更有机的部分,因为它在特定的使用场景中有定义良好的角色,例如定义空集合或异常退出函数调用。Null.isInstanceOf[MyLinkedList[Int]]
这不会抛出NPE吗?scala是否有一个从null
到None或其他东西的隐式转换?@falmari,null
是scala中的一个对象(和其他所有东西一样)@ghik:这与java向后兼容吗?@ghik:首先,null
肯定不是一个对象。缺少类型(在Scala land中)为AnyRef子类型的对象。其次,“Scala中的所有内容都是对象”这一说法并不正确,只是Scala中的每个值都可以被视为对象(看起来像是类的实例)。与Java的基本类型(Scala的AnyVal
的子类型)相对应的类型没有统一包装在类实例中,而是只根据需要装箱。@RandallSchulz好的,我的评论不准确。我只是想到了这一点:“Scala中的所有值都是对象(包括数值和函数)”——如果我理解得很好,null
也不例外。但这当然并不意味着所有的值都在JVM/CLR中表示为对象。首先——这不是我问题的答案:)其次——给定的类MyLinkedList
在没有null
的情况下如何实现?将None
传递到MyLinkedList
--val l:MyLinkedList[Int]=新的MyLinkedList(1,None)
会导致编译错误:类型不匹配;找到:None.type(具有基础类型对象None)required:Hi.MyLinkedList[Int]
@Zapadlo您可以通过在伴随对象中定义空列表而不使用null
。请注意,标准库中的大多数集合都有此功能,例如List
的nil
和Vector
的empty
。@Zapadio通过将选项
作为参数来实现此功能,该参数将包装部分
或无
。这只是null模式的类型安全版本。签名本身需要更改。null似乎是一些神秘的东西,不能乱来:)