scala - 模式匹配中使用的抽象类型的类型不匹配

标签 scala generics

此代码编译时出现错误:

def f1[T](e: T): T = e match {
  case i:Int => i
  case b:Boolean => b
}
// type mismatch;
// found   : i.type (with underlying type Int)
// required: T
// case i:Int => i ...

从类型检查的角度来看,这段实现 GADT 的代码看起来非常相同,但编译时没有错误:
sealed trait Expr[T]
case class IntExpr(i: Int) extends Expr[Int]
case class BoolExpr(b: Boolean) extends Expr[Boolean]

def eval[T](e: Expr[T]): T = e match {
  case IntExpr(i) => i
  case BoolExpr(b) => b
}

在模式匹配表达式中的两种情况下,我们都知道 b 国际 bool .为什么第一个示例编译失败而第二个示例编译成功?

最佳答案

第一种情况是不合理的,因为您低估了 Scala 类型系统中类型的多样性。如果,当我们使用 case i:Int 时,这是有道理的。我们知道的分支 TInt ,或者至少是 Int 的父类(super class)型.但它不一定是!例如。可能是 42.typetagged type .

第二种情况没有这样的问题,因为来自 IntExpr <: Expr[T] ,编译器确实知道 T必须正好 Int .

关于scala - 模式匹配中使用的抽象类型的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52479695/

相关文章:

java - 序列化 Scala 案例类并在 Java 中反序列化它们

scala - 如何在 Scala Play2 微服务的根目录中轻松提供 Swagger UI?

c# - 从 C# 中的 List<T> 中删除重复项

java - 在通用列表中插入删除的元素

scala - Intellij-idea 中的 scala 类、脚本和工作表有什么区别?

html - 如何在Scala Play中将“onclick”事件应用于多个单选按钮选项?

generics - 如何调用像 std::num::Float::epsilon() 这样的静态特征方法?

ios - 转换为不相关的类型总是失败

c++ - 为构造函数重用可变参数模板

scala - Spark `reduceGroups`错误重载方法与替代方案