Scala泛型函数返回类型 [英] scala generic function return type

查看:345
本文介绍了Scala泛型函数返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试编写具有通用返回类型的函数,但是除非我强制转换返回类型,否则它不起作用.请参见下面的功能getSomething(),我希望它在不进行强制转换的情况下也能正常工作.我在这里可能做错了什么?

I tried writing a function with a generic return type but it doesn't work unless I cast the return type. Please see the function getSomething() below I expected it to work without the casting. What might I be doing wrong here?

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'",这不是很安全,因为取决于我们提供正确的类型.

As Alexey mentions, the instanceOf is needed to force a link between the expected type and the type of the object returned. It's the equivalent of saying: "Compiler, trust me, I'm giving you an 'A'" and it's not very safe as it depends of us to provide a correct type.

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

If we want the type system to figure things out for us, we need to give it some additional information. One way to do that in Scala is to define some factory that knows how to produce instances of our types and evidence that allows that factory to return our specific types.

这是上面代码的一个版本,引入了这种构造,并使用ContextBounds来获取所需类型的正确工厂实例.

This is a version of the code above introducing such construct and using ContextBounds to obtain the right factory instance of the type we want.

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

这篇关于Scala泛型函数返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆