[英]Reuse Scala type as bounds in method definition
Is it possible to write something like this and reuse the HelperTest.AnyHelper type? 是否可以编写这样的东西并重用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 = ""
}
Currently I am forced to write this, since the compiler won't let me: 目前,由于编译器不允许我这样做,我不得不这样做:
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 = ""
}
Or am I completely on the wrong track? 还是我完全走错了路?
I guess you are mistaken about how type parameters in a signature such as def accept[T]
work. 我想您对
def accept[T]
类的签名中的类型参数如何工作感到误解。 The type variable T
in this signature gets bound , that is, T
is introduced as a new type variable. 此签名中的类型变量
T
受到限制 ,即T
被引入为新的类型变量。 If there already exists a type variable with the same name in the current context, then it will be shadowed by the newly bound T
. 如果在当前上下文中已经存在一个具有相同名称的类型变量,那么它将被新绑定的
T
遮盖。 Consider this example: 考虑以下示例:
class Foo[T] {
def id[T](t: T) = t
}
The class signature binds a new T
that can be referred to in the class body. 类签名绑定了可以在类主体中引用的新
T
However, the method signature binds a T
as well, which shadows the class T
. 但是,方法签名也绑定了一个
T
,从而遮盖了类T
With the result, that you can instantiate the class T
with some type X
and the method T
with some other type Y
: 结果是,您可以使用某种类型
X
实例化类T
以及使用其他类型Y
实例化方法T
:
val f = new Foo[String]
f.id(0)
Back to your code. 回到您的代码。 Your signature
你的签名
def accept[HelperTest.AnyHelper](helper : HelperTest.AnyHelper)
thus tries to bind a new type variable HelperTest.AnyHelper
- which the compiler rejects, because type variables may not contain a dot ( .
). 因此尝试绑定一个新的类型变量
HelperTest.AnyHelper
编译器拒绝,因为类型变量可能不包含点( .
)。
Do the following instead: 而是执行以下操作:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.