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

标签 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)
    }

  }

}

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

“partialFunctionBuilder”遵循相同的模式,返回一个用“T”参数化的类型。我不明白我首先展示的代码和 Play 框架代码之间有什么区别。从“testWrappedParametrizedTypes”中删除“<: Expression”总是给我同样的错误。

最佳答案

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

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

关于Scala 函数/方法参数化返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32639527/

相关文章:

generics - 具有通配符类型参数的 Map 上的 flatMap

python - 有没有办法使用 String replace() 方法来替换任何东西

mongodb - Mongo Scala Play - java.lang.NoSuchMethodError : com. mongodb.ConnectionString.getApplicationName()Ljava/lang/String;]

Scala Random创建随机对象时种子会做什么

C# 如何创建 KeyValuePair 的通用列表

java - Android 泛型错误 : The method is not applicable for the arguments

scala - Wartremover 仍会在排除的 Play 路线文件中报告疣

regex - 如何在scala中提取匹配的字符串?

pointers - 戈朗 : Why selector to pointers is illegal after comparison?

java - 编译 .java 文件时无法找到符号错误