继承由内部类型参数化的类 [英] Inherit from a class parametrized by an inner type

查看:37
本文介绍了继承由内部类型参数化的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个类 B ,该类继承自通用类 A ,该类由内部类型为 B 进行了参数化.具体来说,我想要这个(最小化的示例):

I would like to have a class B that inherits from a generic class A that is parametrized by an inner type of B. Specifically, I would like this (minimized example):

class A[T]
class B extends A[T] {
  class T
}

这样编写,编译器不接受.有什么方法可以指定这种继承关系吗?(使用一些不同的语法或技巧).

Written like this, the compiler does not accept it. Is there any way to specify this inheritance relationship? (Using some different syntax, or some tricks.)

如果没有,那么什么是官方参考文件证明这是不可能的?

If not, what would be an official reference documenting that this is not possible?

注释:

  • 是的,我希望 T 成为内部类.我确实希望 B 的单独实例具有不兼容的类型 T .

  • Yes, I want T to be an inner class. I do want separate instances of B to have incompatible types T.

此问题考虑相同的情况,但不询问是否/如何可能,而是询问其他方式来写相同的东西.(至少这就是答案的解释方式.)无论如何,这个问题已有十年历史了,Scala从那以后可能就已经发展了.

This question considers the same situation but does not ask whether/how it is possible, but instead asks for other ways to write the same thing. (At least that's how the answers seem to interpret it.) In any case, that question is ten years old, and Scala may have evolved since.

说明::我希望 B A 继承,而不是从 A ,或具有从 A 继承的内部类 B .原因是我想在以下情况下使用它: A 是类型类. B 应该提供一种快速的方法来轻松生成该类型类的新类(使用最少的样板).我想让该类的用户执行类似的操作: implicit val X = createBInstance(),然后他们将能够使用 XT 类型,它将具有键入类 A .到目前为止,我管理的最好的方法是支持模式 val X = createBInstance();.隐式val xTypeclass = X.typeclass 并使用 X.T .这意味着更多样板,忘记某些东西的可能性,并且对名称空间的污染更大(附加名称 xTypeclass ).(非常好奇: A MLValue.Converter B QuickConverter X Header / RuntimeError /...

Clarification: I want B to inherit from A, not from an inner class of A, or have an inner class of B inherit from A. The reason is that I want to use it in the following situation: A is a type class. B is supposed to provide a quick way to easily generate new classes of that type class (with minimal boilerplate). I want to the user of the class to do something like: implicit val X = createBInstance(), and then they will be able to use the type X.T and it will have type class A. The best I managed so far is to support the pattern val X = createBInstance(); implicit val xTypeclass = X.typeclass and use X.T. This means more boilerplate, the possibility to forget something, and it pollutes the namespace more (additional name xTypeclass). (For the very curious: A is MLValue.Converter, B is QuickConverter, and X is Header/RuntimeError/... in my code.)

推荐答案

您可以尝试

class A {
  type T
}
class B extends A {
  class T
}

val b: B = new B
val t: b.T = new b.T

我将 T 设置为类型成员,而不是类型参数.

I made T a type member rather than type parameter.

在这里,一个类覆盖了一个类型.

Here a class overrides a type.

如果您还想将 T 用作类型参数,则可以引入Aux-type

If you want to use T also as a type parameter you can introduce Aux-type

object A {
  type Aux[_T] = A { type T = _T }
}

,并使用类型 A.Aux [T] 代替原始的 A [T] .

and use type A.Aux[T] as a replacement to your original A[T].

现在您在做

trait A[X]

class B {
  class T

  /*implicit*/ object typeclass extends A[T]
}

val b = new B
implicit val b_typeclass: b.typeclass.type = b.typeclass

val b1 = new B
implicit val b1_typeclass: b1.typeclass.type = b1.typeclass

implicitly[A[b.T]]
implicitly[A[b1.T]]

请注意,现在将对象 typeclass 隐式化是无用的.

Please notice that making object typeclass implicit is now useless.

使对象 typeclass 隐式将很有用.

trait A[X]

class B {
  class T

  implicit object typeclass extends A[T]
}

object b extends B
object b1 extends B

implicitly[A[b.T]]
implicitly[A[b1.T]]

如果要使 B 扩展 A ,那么我早些时候建议用类型成员替换 A 的类型参数. A 仍然是类型类,只是类型成员类型类而不是类型参数类型类

If you want to make B extend A then as earlier I propose to replace type parameter of A with a type member. A will still be a type class, just type-member type class rather than type-parameter type class

trait A {
  type X
}

object A {
  type Aux[_X] = A {type X = _X}
}

class B extends A {
  type X = T

  class T
}

implicit object b extends B
implicit object b1 extends B

implicitly[A.Aux[b.T]]
implicitly[A.Aux[b1.T]]

这篇关于继承由内部类型参数化的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆