Scala中方法类型参数化的结构类型?

Jus*_*s12 11 scala

考虑以下Scala代码(例如,在REPL中)

object A{def foo:Unit = {}}
object B{def foo:Unit = {}}

def bar[T <: Any {def foo: Unit}](param: T*):Unit = param.foreach(x => x.foo)

bar(A, A)  // works fine
bar(B, B)  // works fine
bar(A, B)  // gives error
Run Code Online (Sandbox Code Playgroud)

前两个工作正常.第三个给出错误:

error: inferred type arguments [ScalaObject] do not conform to method bar's type parameter bounds [T <: Any{def foo: Unit}]

有什么方法可以做我想要的吗?

Ben*_*mes 14

这通常称为结构类型,而不是鸭子类型.我编辑了你的头衔.:)

我认为你的问题是由定义类型参数T然后以不变的方式使用它引起的.T只能引用一种具体类型,但你有不同类型的参数AB.

这有效:

 def bar(param: {def foo: Unit}*) = param.foreach(x => x.foo)
Run Code Online (Sandbox Code Playgroud)

编辑:使用类型别名也有效:

 type T = {def foo: Unit}
 def bar(param: T*) = param.foreach(x => x.foo)
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为编译器将简单地替换结构类型来代替其别名T.替换后,此示例与上面的示例完全相同.

  • 它确实在运行时使用反射.请参阅Randall Schulz在此主题中的解释:http://www.scala-lang.org/node/6834 (2认同)