我已经尝试了两种方法将泛型类型参数约束为可空类型,但两者似乎都有一些意想不到的问题.
第一次尝试(使用T <:AnyRef):
scala> def testAnyRefConstraint[T <: AnyRef](option:Option[T]):T = {
| //without the cast, fails with compiler error:
| // "found: Null(null) required: T"
| option getOrElse null.asInstanceOf[T]
| }
testAnyRefConstraint: [T <: AnyRef](Option[T])T
scala> testAnyRefConstraint(Some(""))
res0: java.lang.String =
scala> testAnyRefConstraint(Some(0))
<console>:16: error: inferred type arguments [Int] do not conform to method testAnyRefConstraint's type parameter bounds [T <: AnyRef]
testAnyRefConstraint(Some(0))
Run Code Online (Sandbox Code Playgroud)
这似乎完全符合我的要求,但我不明白为什么需要将null转换为T.
第二次尝试(使用T>:Null):
scala> def testNullConstraint[T >: Null](option:Option[T]):T = {
| option getOrElse null
| }
testNullConstraint: [T >: Null](Option[T])T
scala> …Run Code Online (Sandbox Code Playgroud) 基本上,我希望能够构建一个自定义提取器,而无需在使用它之前将其存储在变量中.
这不是我将如何使用它的一个真实示例,它更可能用于正则表达式或其他字符串模式(如构造),但希望它能解释我正在寻找的内容:
def someExtractorBuilder(arg:Boolean) = new {
def unapply(s:String):Option[String] = if(arg) Some(s) else None
}
//I would like to be able to use something like this
val {someExtractorBuilder(true)}(result) = "test"
"test" match {case {someExtractorBuilder(true)}(result) => result }
//instead I would have to do this:
val customExtractor = someExtractorBuilder(true)
val customExtractor(result) = "test"
"test" match {case customExtractor(result) => result}
Run Code Online (Sandbox Code Playgroud)
当只做一个自定义提取器时,它没有太大的区别,但如果你为case语句构建一个大的提取器列表,它可能会通过将所有提取器与它们的使用分开来使事情变得更难.
我希望答案是不,你不能这样做,但我想我先问一下:D