[英]How to access a class's type parameter in Scala
I have a type-parameterized abstract class that contains a val and a method that both use its type parameter 我有一个类型参数化的抽象类,它包含一个val和一个都使用其类型参数的方法
abstract class Foo[T](val state: T){
def foo(arg: T){
...
}
}
I also have a class that extends this abstract class and provides the type parameter and a value for state
我还有一个扩展这个抽象类的类,它提供了type参数和state
的值
class Bar(myNumber: Int) extends Foo[Int](myNumber){
...
}
I pass an instance of Bar
to another class that accepts any subclass of Foo
, and I would like to call the method foo
on state
, but I'm running into some trouble: 我将一个Bar
实例传递给另一个接受Foo
子类的类,我想调用方法foo
on state
,但是我遇到了一些麻烦:
class Baz(val f: Foo[_]){
f.foo(f.state)
}
This gives the error: 这给出了错误:
<console>:8: error: type mismatch;
found : Baz.this.f.state.type (with underlying type _$1)
required: _$1
f.foo(f.state)
Is there any way to give Baz
knowledge of Bar
's type parameter so that it compiles correctly? 有没有办法让Baz
知道Bar
的类型参数,以便正确编译? Or is that even what I want to do? 或者甚至是我想做什么?
Edit 编辑
To clarify, I have many classes similar to Bar
that extend Foo
and provide their own type parameter, state, and implementation of foo
. 为了澄清,我有许多类似于Bar
类,它们扩展了Foo
并提供了它们自己的类型参数,状态和foo
实现。 I would like users of my library to be able to pass any of them to Baz
without worrying about the type parameter T
since its just an implementation detail of each subclass of Foo
. 我希望我的库的用户能够将其中的任何一个传递给Baz
而不必担心类型参数T
因为它只是Foo
的每个子类的实现细节。
So I would strongly prefer not to do this: 所以我强烈不愿意这样做:
class Baz[T](val f: Foo[T]){
f.foo(f.state)
}
You just need a 你只需要一个
def fooOnState[T](ft: Foo[T]) = ft.foo(ft.state)
calling it with a Foo[_]
is ok. 用Foo[_]
调用它是好的。
Still, existentials are best avoided most of the time, but it depends on your real code. 尽管如此,大多数时候最好避免存在,但这取决于你的真实代码。
Replacing the type parameter with a "type member" in a trait would let you write generic code that works for all state types, at the expense of a little verbosity to specify the type member in each subclass: 用特征中的“类型成员”替换type参数将允许您编写适用于所有状态类型的通用代码,但代价是在每个子类中指定类型成员有点冗长:
trait Foo {
type StateT // this is the "type member"
val state: StateT
def foo(arg: StateT): Unit
}
class Bar(myNumber: Int) extends Foo {
type StateT = Int // this is the verbose part
override val state = myNumber // this, too
override def foo(arg: StateT) { /* something specific here */ }
}
class Baz(val f: Foo) {
f.foo(f.state) // generic code, works on any Foo subclass
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.