【问题标题】:T <: A, return T methodT <: A,返回T方法
【发布时间】:2020-10-05 13:25:09
【问题描述】:

这里是一些示例代码:

trait A
trait B extends A

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

但我得到一个编译错误:

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

如何使它工作? (但最后没有做 asInstanceOf[T] ) 谢谢!

【问题讨论】:

  • 如果我做trait C extends A 然后我打电话给test[C] (这是正确的) 然后它返回一个 B 但我想要一个C?! - 您要解决的元问题是什么;因为这看起来像一个 xy 问题。

标签: scala generics


【解决方案1】:

你的方法的签名

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

承诺对于任何类型 TA 的子类型,您返回此类型的值T。然后你返回了一个B 类型的值。你违反了签名(A 的子类型很多,不仅仅是B)。

例如,您可以尝试一个类型类(通过这种方式,您说您返回的值T 根本不是任何T &lt;: A,而是任何可以由类型类@987654336 处理的T &lt;: A @)

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

@LuisMiguelMejíaSuárez 在他的评论中描述的情况

trait C extends A

你会有

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

关于泛型返回类型另见

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

或者你可以使用标准类型类=:=&lt;:&lt;

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

(not implicit ev: T =:= B)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2017-03-29
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    相关资源
    最近更新 更多