scala - Scala 中可重写的默认类型参数

标签 scala

我正在尝试公开一个使用类型别名参数化的类:

trait Tr[T] {
  var x: T = _
}

abstract class Foo {
  type MyParameter

  class SomeClass extends SomeOtherClass with Tr[MyParameter]
}

class Bar extends Foo {
  override type MyParameter = Int

  val myObj = new SomeClass
  myObj.x = 6
}

class Qux extends Foo {
  override type MyParameter = String

  val myObj = new SomeClass
  myObj.x = "hello" 
}

这很好用。

现在,我想做的是为 MyParameter 类型指定一个默认值。像这样:

abstract class Foo {
  type MyParameter = String
  // ...
}

// ...

class Qux extends Foo {
  val myObj = new SomeClass
  myObj.x = "hello"
}

但是,如果我这样做,Bar 类将因类型错误而失败——显然,此时 SomeClass 已经固定为 String.

我该怎么做才能解决这个问题?或者,我可以采用什么其他方法让 SomeClass 由具有默认值但可以在 Foo 的子类中覆盖的类型参数化?

请注意,SomeClass 将比显示的更复杂,因此我不希望用户必须覆盖 SomeClass 的定义。此外,所有对 X.SomeClass 的使用都应使用相同的 Tr[T],因此我不想让 SomeClass 本身可参数化。

最佳答案

如果您省略分配,您可以找到问题的根本原因:

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait T[T] {
  var x: T = _
}

abstract class Foo {
  type Param = String

  class Child extends T[Param]
}

class Bar extends Foo {
  (new Child).x = "foo"
}

class Qux extends Foo {
  override type Param = Int
}

// Exiting paste mode, now interpreting.

<pastie>:26: error: overriding type Param in class Foo, which equals String;
 type Param has incompatible type
  override type Param = Int

覆盖类型遵循与覆盖 defvalvar 相同的规则:覆盖类型必须与类型兼容它是压倒一切的。

例如,您不能以相同的方式覆盖 toString 以返回 Int

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Test {
  override def toString: Int = 1
}

// Exiting paste mode, now interpreting.

<pastie>:12: error: overriding method toString in class Object of type ()String;
 method toString has incompatible type
  override def toString: Int = 1
               ^

我的建议是拆分层次结构,因此当您需要将具有 Tr[String]Foo 转换为 FooString 时,如果您需要其他类型,您可以扩展 Foo

关于scala - Scala 中可重写的默认类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56758023/

相关文章:

scala - 从 Map[String, Type] 生成案例类?

java - 任务在 Spark 中不可序列化

scala - 如何将宏用于简洁、类型安全、未装箱的枚举?

inheritance - scala 中亚型多态性的替代方法是什么?

scala - 即使我正在使用变量,也会收到未使用的变量警告

scala:在执行输入转换时从类型 T 到类型 T 的通用函数

scala - SIGINT 后在 IntelliJ IDEA 中重新启动 SBT Shell

scala - Scala中的整数到二进制

scala - 插入排序在我用 Scala 编写的代码中不起作用

mongodb - Mongo 时区聚合