Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的方法推广_Scala_Generics - Fatal编程技术网

Scala中的方法推广

Scala中的方法推广,scala,generics,Scala,Generics,我尝试将提供类型安全API的方法概括如下: abstract class AbstractCommand { type T = this.type def shuffler(s: T => Seq[AbstractCommand]) } class TestCommand extends AbstractCommand { override def shuffler(s: (TestCommand) => Seq[AbstractCommand]): Unit = ??

我尝试将提供类型安全API的方法概括如下:

abstract class AbstractCommand {
  type T = this.type
  def shuffler(s: T => Seq[AbstractCommand])
}

class TestCommand extends AbstractCommand {
  override def shuffler(s: (TestCommand) => Seq[AbstractCommand]): Unit = ??? //error
}
我希望函数参数的预期类型在此层次结构中是最具体的。但它不起作用


有没有一种方法可以在Scala中执行类似的操作而不引入一些助手类型参数?

您可以避免在抽象类中定义T:

abstract class AbstractCommand {
  type T
  def shuffler(s: T => Seq[AbstractCommand])
}

class TestCommand extends AbstractCommand {
  type T = TestCommand
  override def shuffler(s: (TestCommand) => Seq[AbstractCommand]): Unit = ??? //compiles !
}

缺点是,它有点冗长,优点是,它更通用

我不完全确定它是否适合您的需要,但我已经能够编译并运行以下内容,请告诉我它是否有帮助:

abstract class AbstractCommand {
  def shuffler(s: this.type => Seq[AbstractCommand])
}

class TestCommand extends AbstractCommand {
  override def shuffler(s: (TestCommand.this.type) => Seq[AbstractCommand]): Unit = {
    s(this)
    println("success")
  }
}

new TestCommand().shuffler(_ => Seq.empty) // prints "success"

这看起来是一个完美的用例:

抽象类抽象命令[T
def shuffler(s:T=>Seq[AbstractCommand[T]]
}
类TestCommand扩展了AbstractCommand[TestCommand]{
覆盖def shuffler(s:(TestCommand)=>Seq[AbstractCommand[TestCommand]]):单位=???
}
并使用类型成员而不是类型参数(使用提供的示例):

抽象类抽象命令{self=>

类型T>:self.type带有“最派生的”您是指“最具体的”?@stefanobaghino Yes您可以试试F-boundedpolymorphism@dk14我也这么认为,但我相信St.Antario希望避免使用类型参数。@stefanobaghino作为一种折衷方案,您可以使用类型成员(但仍然必须在派生类中手动分配它们)问题是,我希望我能得到的唯一最具体的类型是,
TestCommand
是最具体的类型(因为它是
AbstractCommand
的专门化)只有这样才能为特定的实现所接受;你能给我一个例子来澄清你的观点吗?也许可以用一个要点或类似的东西。事实上,是的。F-bound多态性是一个解决方案,但要明确的是,这不是F-Bounded多态性,它需要一个类型参数。你可以在这里找到更多关于它的信息:@stefanobaghino我不确定你是否知道,只是在回答中没有提到这一点,但是
this.type
这里比
TestCommand
更具体。如果你尝试作者想要的签名(
defshuffler(s:TestCommand=>Seq[AbstractCommand]):Unit
)除非我算错了方差,否则它不会编译。同意,已经理解了。但我想你忘记了抽象类中的
self:t=>
。@St.Antario肯定。没有看到你们已经在另一个答案的评论中谈论过这一点:XBtw。你不知道是否可以用类型成员实现F-有界多态性吗?不是generic类型。你是说使用类型成员而不是类型参数?非常感谢。明白。
abstract class AbstractCommand[T <: AbstractCommand[T]] {
  self: T =>
  def shuffler(s: T => Seq[AbstractCommand[T]])
}

class TestCommand extends AbstractCommand[TestCommand] {
  override def shuffler(s: (TestCommand) => Seq[AbstractCommand[TestCommand]]): Unit = ???
}
abstract class AbstractCommand { self =>
  type T >: self.type <: AbstractCommand
}

class TestCommand extends AbstractCommand {
  type T = TestCommand
}

class OtherCommand extends AbstractCommand {
  type T = OtherCommand
}