【发布时间】:2019-04-24 19:51:19
【问题描述】:
假设你有这样的特质:
trait Foo[A]{
def foo: A
}
我想创建一个这样的函数:
def getFoo[A <: Foo[_]](a: A) = a.foo
Scala 编译器为该函数的返回类型推导出 Any。
如何在getFoo 的签名(或正文)中引用匿名参数_?
换句话说,如何取消匿名化参数?
我希望能够使用类似的功能
object ConcreteFoo extends Foo[String] {
override def foo: String = "hello"
}
val x : String = getFoo(ConcreteFoo)
由于明显的原因导致编译失败,因为 getFoo 被隐式声明为 Any。
如果使用 Scala(2.12 版)无法做到这一点,我会对这种限制的理性或技术原因感兴趣。 我确信有关于此的文章和现有问题,但我似乎缺少正确的搜索词。
更新:现有答案准确地回答了我的问题,但我想我对我的实际用例不够准确。对困惑感到抱歉。我希望能够写作
def getFoo[A <: Foo[_]] = (a: A) => a.foo
val f = getFoo[ConcreteFoo.type]
//In some other, unrelated place
val x = f(ConcreteFoo)
因为我没有A类型的参数,如果有,编译器无法推导出参数R和A
def getFoo[R, A <: Foo[R]]: (A => R) = (a: A) => a.foo
喜欢建议。我想避免手动提供类型参数R(在这种情况下为String),因为它感觉多余。
【问题讨论】:
-
他们称它为“匿名”正是因为它没有名称,因此无法引用。所以,“去匿名化”的字面意思是“给它一个名字”:
def getFoo[B, A <: Foo[B]](a: A): B = a.foo