Type mismatch on abstract type used in pattern matching

前端 未结 3 1208
夕颜
夕颜 2020-12-03 11:25

This code compiles with an error:

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


        
3条回答
  •  情书的邮戳
    2020-12-03 12:05

    You ask of your function to return a type T, then you pattern-match against Int and Boolean. Except your function has no evidence that Int and Boolean are also of type T: when you pattern-match, you introduce the constraint that Int <: T and Boolean <: T. You could either replace the return type T by a fixed type like String and return a String, or introduce a constraint that will satisfy both the case Int and Boolean.

    //this compiles
    def f1[T](e: T ): String = e match {
      case _:Int => "integer"
      case _:Boolean => "boolean"
    }
    
    //this compiles too, but will return AnyVal
    def f1[T >: AnyVal](e: T ): T = e match {
       case i:Int => i
       case b:Boolean => b
    }
    

    Basically you can't just return any type T dynamically because you need to prove at compile time that your function type-checks out.

    The other function in your example avoids the issue by encapsulating type constraints within case classes IntExpr <: Expr[Int] and BoolExpr <: Expr[Boolean] (notice how Expr[_] would be the equivalent of T in the constraints I mentioned above). At compile time, T is properly identified in all cases (e.g in the IntExpr you know it's an Int)

提交回复
热议问题