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

时间:2015-09-17 20:35:49

标签: scala generics methods types 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()
           ^

我认为之前显示的代码应该可行。在第一种方法中,我返回类型T而T没有约束。编译器错误也出现在第二种方法中,但参数化类型也符合返回的对象类型。

另外,几个星期前我编写了一个代码,看起来像没有编译的代码(这不是一个有效的例子,因为这段代码是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)
    }

  }

}

如您所见,我成功定义了函数&#34; partialFunctionBuilder&#34;我正在使用它。

&#34; partialFunctionBuilder&#34;遵循相同的模式,返回一个用&#34; T&#34;参数化的类型。我不知道我首先展示的代码与Play Framework代码之间的区别。删除&#34;&lt;:Expression&#34;来自&#34; testWrappedParametrizedTypes&#34;不断给我同样的错误。

1 个答案:

答案 0 :(得分:2)

当函数具有带有某些约束的类型参数时,应该可以使用任何参数调用它,从而满足这些约束。因此,根据定义,可以调用testParametrizedTypes[String]()testWrappedParametrizedTypes[ExpImpl2]()。但是因为在这两种情况下都会返回固定类型ExpImpl1Option[ExpImpl1],所以存在类型不匹配。

在Play示例中, 可以使用任何类型partialFunctionBuilder调用T,如果您传递正确的函数,则返回该类型{{1} }}