简体   繁体   English

特征中的自动推断泛型类型

[英]Automatically inferred generic type in trait

I want a generic base class which can be mixed in some traits. 我想要一个可以混合在某些特征中的通用基类。

Is it possible to have the mixins automatically adopt the generic type of the base class? 是否可以让mixins自动采用基类的泛型?

abstract class Base[T] {
  def foo: T = ???
  def bar(value: T): Boolean
}

trait MixinA {
  self: Base[U] => // U should be automatically bound to T of Base[T]
  def bar(value: U): Boolean = false
}

You can achieve something approaching this using an abstract type in Base : 您可以使用Base的抽象类型来实现一些目标:

abstract class Base[T] {
  type U <: T
  def foo: U = ???
  def bar(value: U): Boolean
}

trait MixinA {
  self: Base[_] =>
  final def bar(value: U): Boolean = false
}

REPL test: REPL测试:

scala> class Impl extends Base[Int] with MixinA
defined class Impl

scala> val i = new Impl
i: Impl = Impl@7ca5cc9e

scala> val x: Int = i.foo
scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
  at Base.foo(<console>:9)
  ... 33 elided

As you can see the compiler correctly determined that i.foo is a sub-type of Int (concretely, it is Int ) and thus can be assigned to x (the exception here is just because you have left its body unimplemented). 如您所见,编译器正确地确定i.fooInt的子类型( i.foo ,它 Int ),因此可以分配给x (这里的例外是因为您没有执行它的主体)。

In this case, you need U to be a type parameter of your MixinA . 在这种情况下,您需要U作为MixinA的类型参数。

trait MixinA[U] { self: Base[U] => ...

Type parameters are in a way like function parameters, if they are declared you need to pass them from somewhere (no magic). 类型参数在某种程度上类似于函数参数,如果声明了它们,则需要从某个地方传递它们(没有魔法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM