Scala函数/方法参数化返回类型

Scala函数/方法参数化返回类型,scala,generics,methods,types,return,Scala,Generics,Methods,Types,Return,我刚刚想出了一些我不明白的东西。我试图从方法返回参数化类型,代码如下(工作示例): 我认为前面显示的代码应该可以工作。在第一个方法中,我返回一个类型T,T没有约束。编译器错误也发生在第二个方法中,但是参数化类型也符合返回的对象类型 另外,我在几周前编写了一段代码,看起来编译起来没有问题(这不是一个工作示例,因为这段代码是Play Framework项目的一部分): 如您所见,我成功地定义了函数“partialFunctionBuilder”,并且正在使用它 “partialFunctionBui

我刚刚想出了一些我不明白的东西。我试图从方法返回参数化类型,代码如下(工作示例):

我认为前面显示的代码应该可以工作。在第一个方法中,我返回一个类型T,T没有约束。编译器错误也发生在第二个方法中,但是参数化类型也符合返回的对象类型

另外,我在几周前编写了一段代码,看起来编译起来没有问题(这不是一个工作示例,因为这段代码是Play Framework项目的一部分):

如您所见,我成功地定义了函数“partialFunctionBuilder”,并且正在使用它


“partialFunctionBuilder”遵循相同的模式,返回一个用“T”参数化的类型。我看不出我首先展示的代码和Play框架代码之间有什么区别。删除“当函数具有带有某些约束的类型参数时,应该可以使用满足这些约束的任何参数调用它。因此,给定定义,应该可以调用
testParameterizedTypes[String]()
testwrappedParameterizedTypes[ExpImpl2]()
。但由于在这两种情况下都返回固定类型
ExpImpl1
,或
选项[ExpImpl1]
,因此类型不匹配


在Play示例中,可以使用任何类型的
T
调用
partialFunctionBuilder
,如果您向它传递正确的函数,这些函数返回该类型
T
,返回类型
testParameterizedTypes
是T。但是您返回的值类型是
ExpImp1
。编译器不得不抱怨。为什么你对此感到困惑吗?@I.K.因为ExpImp1是表达式的一个子类型,不是吗?请参阅第二种方法“TestWrappedParametricedTypes”“是的,没错,但这与类型参数T有什么关系?编译器无法推断任何关系,因此它必须抱怨。@好的,为什么编译器在Play Framework示例中不抱怨?因为它没有返回类型参数,所以它返回的是PartialFunction类型。这是不同的。请看另一个相关示例:;本回购协议适用于以下博文:
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]) {

  }

}
Error:(10, 12) type mismatch;
 found   : ExpImp1
 required: T
    ExpImp1()
           ^
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)
    }

  }

}