Scala function/method 参数化 return 类型
Scala function/method parametrized return type
我刚刚想出了一些我不明白的东西。我正在尝试从方法中 return 参数化类型,代码如下(工作示例):
trait Expression
case class ExpImp1() extends Expression
case class ExpImp2() extends Expression
object Main {
private def testParametrizedTypes[T](): T = {
ExpImp1()
}
private def testWrappedParametrizedTypes[T <: Expression](): Option[T] = {
Some(new ExpImp1())
}
def main(args: Array[String]) {
}
}
但是当我编译这段代码时,编译器说(IDE 警告我两个函数中的相同错误):
Error:(10, 12) type mismatch;
found : ExpImp1
required: T
ExpImp1()
^
我认为之前显示的代码应该可以工作。在第一种方法中,我 returning 类型 T 并且 T 没有约束。第二种方法也出现编译错误,但是参数化类型也符合returned对象类型。
此外,几周前我写了一段代码,看起来编译没有问题(这不是一个工作示例,因为这段代码是 Play Framework 项目的一部分):
class CanBeAuthenticatedRequest[A](val request: Request[A]) extends WrappedRequest[A](request)
class UnauthenticatedRequest[A](override val request: Request[A]) extends CanBeAuthenticatedRequest(request)
class AuthenticatedRequest[A](val user: String, override val request: Request[A]) extends CanBeAuthenticatedRequest[A](request)
object CanBeAuthenticatedAction extends ActionBuilder[CanBeAuthenticatedRequest] {
def invokeBlock[A]...
}
object Fold {
private def partialFunctionBuilder[T](authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T):
PartialFunction[CanBeAuthenticatedRequest[_], T] = {
case ar: AuthenticatedRequest[_] => authenticated(ar)
case ur: UnauthenticatedRequest[_] => unauthenticated(ur)
}
def apply[T](request: CanBeAuthenticatedRequest[_])
(authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T): T = {
partialFunctionBuilder(authenticated)(unauthenticated)(request)
}
}
}
如您所见,我成功定义了函数 "partialFunctionBuilder" 并且正在使用它。
"partialFunctionBuilder" 遵循相同的模式,returning 一个用 "T" 参数化的类型。我看不出我首先展示的代码和 Play Framework 代码之间有什么区别。从 "testWrappedParametrizedTypes" 中删除 "<: Expression" 总是给我同样的错误。
当一个函数的类型参数有一些约束时,应该可以用任何参数调用它,满足这些约束。所以根据定义应该可以调用 testParametrizedTypes[String]()
或 testWrappedParametrizedTypes[ExpImpl2]()
。但是因为在这两种情况下你return一个固定类型ExpImpl1
,或者Option[ExpImpl1]
,存在类型不匹配。
并且在 Play 示例中, 可以使用任何类型 T
调用 partialFunctionBuilder
,如果您将正确的函数传递给它,return 类型 T
.
我刚刚想出了一些我不明白的东西。我正在尝试从方法中 return 参数化类型,代码如下(工作示例):
trait Expression
case class ExpImp1() extends Expression
case class ExpImp2() extends Expression
object Main {
private def testParametrizedTypes[T](): T = {
ExpImp1()
}
private def testWrappedParametrizedTypes[T <: Expression](): Option[T] = {
Some(new ExpImp1())
}
def main(args: Array[String]) {
}
}
但是当我编译这段代码时,编译器说(IDE 警告我两个函数中的相同错误):
Error:(10, 12) type mismatch;
found : ExpImp1
required: T
ExpImp1()
^
我认为之前显示的代码应该可以工作。在第一种方法中,我 returning 类型 T 并且 T 没有约束。第二种方法也出现编译错误,但是参数化类型也符合returned对象类型。
此外,几周前我写了一段代码,看起来编译没有问题(这不是一个工作示例,因为这段代码是 Play Framework 项目的一部分):
class CanBeAuthenticatedRequest[A](val request: Request[A]) extends WrappedRequest[A](request)
class UnauthenticatedRequest[A](override val request: Request[A]) extends CanBeAuthenticatedRequest(request)
class AuthenticatedRequest[A](val user: String, override val request: Request[A]) extends CanBeAuthenticatedRequest[A](request)
object CanBeAuthenticatedAction extends ActionBuilder[CanBeAuthenticatedRequest] {
def invokeBlock[A]...
}
object Fold {
private def partialFunctionBuilder[T](authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T):
PartialFunction[CanBeAuthenticatedRequest[_], T] = {
case ar: AuthenticatedRequest[_] => authenticated(ar)
case ur: UnauthenticatedRequest[_] => unauthenticated(ur)
}
def apply[T](request: CanBeAuthenticatedRequest[_])
(authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T): T = {
partialFunctionBuilder(authenticated)(unauthenticated)(request)
}
}
}
如您所见,我成功定义了函数 "partialFunctionBuilder" 并且正在使用它。
"partialFunctionBuilder" 遵循相同的模式,returning 一个用 "T" 参数化的类型。我看不出我首先展示的代码和 Play Framework 代码之间有什么区别。从 "testWrappedParametrizedTypes" 中删除 "<: Expression" 总是给我同样的错误。
当一个函数的类型参数有一些约束时,应该可以用任何参数调用它,满足这些约束。所以根据定义应该可以调用 testParametrizedTypes[String]()
或 testWrappedParametrizedTypes[ExpImpl2]()
。但是因为在这两种情况下你return一个固定类型ExpImpl1
,或者Option[ExpImpl1]
,存在类型不匹配。
并且在 Play 示例中, 可以使用任何类型 T
调用 partialFunctionBuilder
,如果您将正确的函数传递给它,return 类型 T
.