T <: A, return T method

痞子三分冷 提交于 2021-02-05 11:33:05

问题


here is some sample code:

trait A
trait B extends A

def test[T <: A](): T = {
  new B {}
}

but I get an compile error:

type mismatch;
found   : B
required: T
new B {}

how to make it working ? ( but without doing asInstanceOf[T] at the end ) thanks!


回答1:


The signature of your method

def test[T <: A](): T

promises that for any type T that is a subtype of A you return a value of this type T. And then you returned a value of type B. You violated the signature (there are many subtypes of A, not only B).

For example you can try a type class (in this way you say that you return a value of T not for any T <: A at all but for any T <: A that can be handled by the type class MakeT)

def test[T <: A]()(implicit makeT: MakeT[T]): T = makeT.makeT()

trait MakeT[T] { // or MakeT[+T]
  def makeT(): T
}

object MakeT {
  implicit val bMakeT: MakeT[B] = () => new B {}
  // or implicit def bMakeT[T >: B]: MakeT[T] = () => new B {}
}

test[B]().isInstanceOf[B] // true

In the situation described by @LuisMiguelMejíaSuárez in his comment

trait C extends A

you'll have

// test[C]() // doesn't compile, could not find implicit value for parameter makeT: MakeT[C]

Regarding generic return type see also

Why can't I return a concrete subtype of A if a generic subtype of A is declared as return parameter?

Type mismatch on abstract type used in pattern matching

Or you can use standard type classes =:=, <:<

def test[T <: A]()(implicit ev: B =:= T): T = {
  new B {}
}

(not implicit ev: T =:= B)

or

def test[T <: A]()(implicit ev: B <:< T): T = {
  new B {}
}


来源:https://stackoverflow.com/questions/64209514/t-a-return-t-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!