scala - 在 Scala 中利用泛型返回类型
问题描述
所以我想使用一个通用的返回类型,并能够在函数中使用该类型的信息。不确定这是可能的,但这是我想要的:
def getStuff[A](a: MyObj, b: String): Option[A] = {
// do some stuff
A match {
case String => Some(a.getString(b))
case Integer => Some(a.getInt(b))
...
case _ => None
}
}
但是,如您所知,A match
这是不可能的。关于如何实现这一目标的任何想法?
解决方案
这是使用类型类的经典案例:
trait StuffGetter[T] { // typeclass
def get(obj: MyObj, s: String): Option[T]
}
implicit val stringGetter = new StuffGetter[String] {
def get(o: MyObj, s: String): Option[String] = ???
}
implicit val intGetter = new StuffGetter[Int] {
def get(o: MyObj, s: String): Option[Int] = ???
}
def getStuff[A](a: MyObj, b: String)(implicit ev: StuffGetter[A]): Option[A] =
ev.get(a, b)
val stuff0 = getStuff[String](obj, "Hello") // calls get on stringGetter
val stuff1 = getStuff[Int](obj, "World") // call get on intGetter
val stuff2 = getStuff[Boolean](obj, "!") // Compile-time error
StuffGetter
trait 定义了您想要对泛型类型执行的操作,并且该 trait 的每个值implicit
都提供了特定类型的实现。(对于自定义类型,这些通常放置在该类型的伴随对象中;编译器将在那里查找它们)
当getStuff
被调用时,编译器将寻找具有匹配类型的implicit
实例。StuffGetter
如果不存在这样的实例,这将失败,否则将在ev
参数中传递。
这样做的好处是“匹配”是在编译时完成的,并且在编译时也会检测到不支持的类型。
推荐阅读
- unity3d - unity:图像的不透明区域应该是碰撞器,透明区域不应该
- javascript - 如何正确排序 d3 气泡图的数据,以使较小的气泡显示在较大的气泡之上?
- lua - humanoid.health 始终为 100,但实际上不是 100
- python - 如何正确编写此 if 语句?
- mongodb - MongoDB在单个文档中聚合数组
- typescript - Typescript 无法识别导入的枚举并抛出 TypeError
- html - css 使项目与网格水平对齐
- excel - 在 Office 365 中,如何使用 VBA 让 Excel 数组函数在工作表中正确溢出和呈现
- amazon-web-services - AWS Amplify API 未触发 Lambda
- angular - 如何从 Angular ngModule 文件中获取组件文件路径列表?