Scala - 使用复杂的泛型获取 subclass 和另一个 class 的信息 - 无法编译?
Scala - Using complicated generics to get information of a subclass and another class - doesn't compile?
我正在用 scala 编写一个程序,该程序使用以下框架:
trait Tool[T <: Tool[T, U], U <: Settings[T]] {
// members here
def createSettingsFrom(settingsWithStringNames: Map[String, _]): U
}
trait Settings[T <: Tool[T, _ <: Settings[T]]
在Tool中,T是子class,U是class,为它携带信息。每个工具都可以看作是一种带有参数的命令,这些参数是为每个工具自定义的。
我还有一个扩展它的 class,以及它的 "information carrier":
object Cleanup extends Tool[Cleanup, CleanupSettings] {
override def createSettingsFrom(settings: Map[String, _]): CleanupSettings
= CleanupSettings(
settings.get("attribute1").asInstanceOf[Int]
settings.get("attribute2").asInstanceOf[String])
}
case class CleanupSettings extends Settings[Cleanup](
//attribute1: Int,
//attribute2: String
//more attributes)
当我尝试编译这些 classes 时,我得到以下堆栈跟踪:
Information:21/10/16 03:20 - Compilation completed with 2 errors and 0 warnings in 3s 200ms
/project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/Cleanup.scala
Error:(17, 24) type arguments [package.tools.operations.cleanup.Cleanup,package.tools.operations.cleanup.CleanupSettings] do not conform to trait ConfigurableTool's type parameter bounds [T <: package.tools.ConfigurableTool[T,U],U <: package.tools.params.Settings[T]]
object Cleanup extends ConfigurableTool[Cleanup, CleanupSettings] {
^
/project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/CleanupSettings.scala
Error:(11, 11) type arguments [package.tools.operations.cleanup.Cleanup] do not conform to trait Settings's type parameter bounds [T <: package.tools.Tool[T, _ <: package.tools.params.Settings[T]]]
extends Settings[Cleanup]
^
我还有一个特征 ConfigurableTool,它只是 Tool 的扩展,具有一些额外的功能,因此它具有完全相同的通用签名,只是 extends Tool[T, U]
.
我尝试了多种方法来解决这个问题,包括将 + 和 - 的组合添加到我的泛型中以实现协变和逆变,但没有帮助。
我确实考虑过为我的设置使用动态类型,但速度是一个因素。我什至不知道这样做是否能解决问题。
就是这样,我希望你有时间来帮助我,如果没有,还是感谢阅读!
我无法重现您收到的错误消息。
代码中有一些拼写错误,但在清理它们之后,唯一剩下的错误是 Cleanup
的定义,在扩展特征时不能将其作为类型参数传递。
object Cleanup extends Tool[Cleanup.type, CleanupSettings] { ... }
illegal cyclic reference involving object Cleanup
您可以通过将其作为特征并在伴随对象中扩展它来解决这个问题。这是完整的代码:
trait Tool[T <: Tool[T, U], U <: Settings[T]] {
// members here
def createSettingsFrom(settingsWithStringNames: Map[String, _]): U
}
trait Settings[T <: Tool[T, _ <: Settings[T]]]
trait Cleanup extends Tool[Cleanup, CleanupSettings] {
override def createSettingsFrom(settings: Map[String, _]): CleanupSettings = CleanupSettings(
settings.get("attribute1").asInstanceOf[Int],
settings.get("attribute2").asInstanceOf[String])
}
object Cleanup extends Cleanup
case class CleanupSettings(
attribute1: Int,
attribute2: String) extends Settings[Cleanup]
我正在用 scala 编写一个程序,该程序使用以下框架:
trait Tool[T <: Tool[T, U], U <: Settings[T]] {
// members here
def createSettingsFrom(settingsWithStringNames: Map[String, _]): U
}
trait Settings[T <: Tool[T, _ <: Settings[T]]
在Tool中,T是子class,U是class,为它携带信息。每个工具都可以看作是一种带有参数的命令,这些参数是为每个工具自定义的。
我还有一个扩展它的 class,以及它的 "information carrier":
object Cleanup extends Tool[Cleanup, CleanupSettings] {
override def createSettingsFrom(settings: Map[String, _]): CleanupSettings
= CleanupSettings(
settings.get("attribute1").asInstanceOf[Int]
settings.get("attribute2").asInstanceOf[String])
}
case class CleanupSettings extends Settings[Cleanup](
//attribute1: Int,
//attribute2: String
//more attributes)
当我尝试编译这些 classes 时,我得到以下堆栈跟踪:
Information:21/10/16 03:20 - Compilation completed with 2 errors and 0 warnings in 3s 200ms
/project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/Cleanup.scala
Error:(17, 24) type arguments [package.tools.operations.cleanup.Cleanup,package.tools.operations.cleanup.CleanupSettings] do not conform to trait ConfigurableTool's type parameter bounds [T <: package.tools.ConfigurableTool[T,U],U <: package.tools.params.Settings[T]]
object Cleanup extends ConfigurableTool[Cleanup, CleanupSettings] {
^
/project_folder/src/main/scala/io/oreville/maptools/operations/cleanup/CleanupSettings.scala
Error:(11, 11) type arguments [package.tools.operations.cleanup.Cleanup] do not conform to trait Settings's type parameter bounds [T <: package.tools.Tool[T, _ <: package.tools.params.Settings[T]]]
extends Settings[Cleanup]
^
我还有一个特征 ConfigurableTool,它只是 Tool 的扩展,具有一些额外的功能,因此它具有完全相同的通用签名,只是 extends Tool[T, U]
.
我尝试了多种方法来解决这个问题,包括将 + 和 - 的组合添加到我的泛型中以实现协变和逆变,但没有帮助。 我确实考虑过为我的设置使用动态类型,但速度是一个因素。我什至不知道这样做是否能解决问题。
就是这样,我希望你有时间来帮助我,如果没有,还是感谢阅读!
我无法重现您收到的错误消息。
代码中有一些拼写错误,但在清理它们之后,唯一剩下的错误是 Cleanup
的定义,在扩展特征时不能将其作为类型参数传递。
object Cleanup extends Tool[Cleanup.type, CleanupSettings] { ... }
illegal cyclic reference involving object Cleanup
您可以通过将其作为特征并在伴随对象中扩展它来解决这个问题。这是完整的代码:
trait Tool[T <: Tool[T, U], U <: Settings[T]] {
// members here
def createSettingsFrom(settingsWithStringNames: Map[String, _]): U
}
trait Settings[T <: Tool[T, _ <: Settings[T]]]
trait Cleanup extends Tool[Cleanup, CleanupSettings] {
override def createSettingsFrom(settings: Map[String, _]): CleanupSettings = CleanupSettings(
settings.get("attribute1").asInstanceOf[Int],
settings.get("attribute2").asInstanceOf[String])
}
object Cleanup extends Cleanup
case class CleanupSettings(
attribute1: Int,
attribute2: String) extends Settings[Cleanup]