Null 作为 scala 中的参数默认值会产生类型不匹配错误



为了进行重载调用,例如

val myPage: DocumentType;
func()
func(myPage)

我写了一个函数:

def func(page: DocumentType = null): Unit = {...}

但收到以下错误:

type mismatch; found : Null(null) required: DocumentType

当我将文档类型更改为字符串时,错误消失了。第一个问题:为什么? 文档类型是库中我无法更改的类型,具有以下定义:

type DocumentType <: Document
trait Document

我不希望在每次客户端调用时都将实际参数包装到 Option(如Option(myPage)),但还有其他选项可以获得类似的吗?

你可以重载函数,比如

def func(): Unit = { }  // do what you would do with null
def func(page: DocumentType): Unit = { }  // do what you would do with a DocumentType

您可以通过让两者调用其他私有函数来抽象实现以使其保持干燥。然后,您可以拨打func()func(new DocumentType())

原始答案(不太好)

def func(page: DocumentType): Unit = func(Some(page))
def func(page: Option[DocumentType] = None): Unit = ???

意味着您不需要求助于null.您丢失了干净的 API,因为您可以调用

val d = new DocumentType()
func()
func(d)
func(Some(d))
func(None)

这样的事情应该可以工作:

trait Document
trait DocumentFunc {
// The trick is to tell the compiler that your type can be nullable.
type DocumentType >: Null <: Document
def fun(page: DocumentType = None.orNull): Unit = {
println(page)
}
}

显然,问题是由于您只将上限设置为Document,编译器将拒绝null,因为DocumentType可能会被覆盖以Nothing
而且"显然">null不能在预期Nothing的地方使用。

第一个免责声明:我同意乔尔·伯克利的观点,你应该避免null,我更喜欢他的解决方案。
我只是想回答真正的问题:">为什么它不起作用"。

第二个免责声明:我使用None.orNull只是为了没有明确的null- 那只是因为我使用的短绒不允许使用null
如果需要,您可以更改它。

第三免责声明:Type Members几乎总是可以通过Type Parameters进行更改,(通常)更易于使用,并且更"类型安全"。
Type Members恕我直言,应该只在你真正需要它们的时候使用,比如path dependent types- 更多信息可以在这里找到。

第四个免责声明:使用nullUnit(如果你有的话,还有vars)是使用Scala作为Java的症状,这(通常)是对该语言的不良使用。然而,这只是我的意见。

相关内容

  • 没有找到相关文章

最新更新