2

是否可以编写这样的内容并重用 HelperTest.AnyHelper 类型?

class HelperUtil 
{    
/* this is what I would like to write... reuse the AnyHelper type in the definition */
   def accept[HelperTest.AnyHelper](helper : HelperTest.AnyHelper) = 
   {
       // code here
   }
}

object HelperTest 
{
    type AnyHelper = T forSome { type T <: GenericHelper }
}

abstract class GenericHelper 
{
    val name = ""
}

目前我被迫写这个,因为编译器不会让我:

class HelperUtil 
{
/* gets too verbose, if the generic type gets more complex and would be useful to reuse the type */
    def accept[T <: GenericHelper](helper : T) = 
    {
        // code here
    }
}

abstract class GenericHelper 
{
    val name = ""
}

还是我完全走错了路?

4

1 回答 1

1

我猜你误解了签名中的类型参数是如何def accept[T]工作的。T此签名中的类型变量被绑定,即T作为新的类型变量引入。如果当前上下文中已经存在同名的类型变量,那么它将被新绑定的T. 考虑这个例子:

class Foo[T] {
  def id[T](t: T) = t
}

类签名绑定一个T可以在类主体中引用的新的。但是,方法签名T也绑定了 a ,它隐藏了 class T。结果,您可以实例化具有某种类型的类T和具有某种其他类型X的方法:TY

val f = new Foo[String]
f.id(0)

回到你的代码。你的签名

def accept[HelperTest.AnyHelper](helper : HelperTest.AnyHelper)

因此尝试绑定一个新的类型变量HelperTest.AnyHelper- 编译器拒绝,因为类型变量可能不包含点 ( .)。

请改为执行以下操作:

import scala.language.existentials

trait A
class B1 extends A
class C1 extends B1
class B2 extends A

object HelperUtil {
  type MyA = T forSome { type T <: A }
}

class HelperUtil {
   /* Reuse type declaration */
   def foo(a: HelperUtil.MyA) = println(a.getClass.getName)
   def bar(a: HelperUtil.MyA) = println(a.getClass.getName)
   def baz(a: HelperUtil.MyA) = println(a.getClass.getName)
}

val hu = new HelperUtil

/* Instantiate with different types */
hu.foo(new B1) // B1
hu.foo(new B2) // B2
hu.bar(new C1) // C1
于 2013-03-21T15:55:36.037 回答