为了进行重载调用,例如
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
- 更多信息可以在这里找到。
第四个免责声明:使用null
和Unit
(如果你有的话,还有vars
)是使用Scala作为Java的症状,这(通常)是对该语言的不良使用。然而,这只是我的意见。