【问题标题】:Scala function/method parametrized return typeScala 函数/方法参数化的返回类型
【发布时间】:2015-12-14 20:46:36
【问题描述】:

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

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 Framework 代码之间有什么区别。从“testWrappedParametrizedTypes”中删除“<: expression>

【问题讨论】:

  • 返回类型 testParametrizedTypes 是 T。但您返回的是 ExpImp1 类型的 。编译器不得不抱怨。你为什么对此感到困惑?
  • @I.K.因为 ExpImp1 是 Expression 的子类型,不是吗?见第二种方法“testWrappedParametrizedTypes”
  • 是的,没错,但这与类型参数 T 有什么关系呢?编译器无法推断出任何关系,所以它不得不抱怨。
  • @I.K.为什么编译器在 Play Framework 示例中没有报错?
  • 因为它没有返回类型参数,所以它返回的是 PartialFunction 类型。那是不同的。

标签: scala generics methods types return


【解决方案1】:

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

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

【讨论】:

猜你喜欢
  • 2012-10-31
  • 2018-08-10
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 2019-01-19
相关资源
最近更新 更多