scala泛型函数返回类型

我尝试使用泛型返回类型编写函数,但除非我转换返回类型,否则它不起作用.请参阅下面的函数getSomething()我希望它在没有强制转换的情况下工作.我在这里做错了什么?

trait Sup

class Sub extends Sup {
  def getString = "I am Sub"
}

class Sub2 extends Sup {
  def getInt = 100
}

def getSomething[A <: Sup](str: String) : A  = {
  str match {
    case "sub" => getSub.asInstanceOf[A]
    case "sub2" => getSub2.asInstanceOf[A]
  }
}

def getSub(): Sub = {
  new Sub
}

def getSub2() : Sub2 = {
  new Sub2
}

val x = getSomething[Sub]("sub").getString
val y = getSomething[Sub2]("sub2").getInt

解决方法

正如Alexey所提到的,需要instanceOf来强制期望类型和返回对象类型之间的链接.这相当于说:“编译器,相信我,我给你一个’A’”并且它不是很安全,因为它依赖于我们提供正确的类型.

如果我们希望类型系统为我们解决问题,我们需要给它一些额外的信息.在Scala中执行此操作的一种方法是定义一些知道如何生成类型和证据实例的工厂,以允许该工厂返回我们的特定类型.

这是上面引入此类构造的代码一个版本,并使用ContextBounds来获取我们想要的类型的正确工厂实例.

trait Sup 

class Sub extends Sup {
  val str = "I'm a Sub"
}

class Sub2 extends Sup {
  val number = 42
}

trait SupProvider[T <: Sup] {
  def instance:T
}

object SupProvider {
  def getSomeSup[T<:Sup:SupProvider]: T = implicitly[SupProvider[T]].instance
  implicit object SubProvider extends SupProvider[Sub] {
    def instance = new Sub
  }
  implicit object Sub2Provider extends SupProvider[Sub2] {
    def instance = new Sub2
  }  
}

SupProvider.getSomeSup[Sub].str
// res: String = I'm a Sub

SupProvider.getSomeSup[Sub2].number
// res: Int = 42

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...