是否有“更新”的特征,类似于Function1 for apply?

时间:2013-07-22 15:01:24

标签: scala syntax updates traits structural-typing

Scala允许定义update,例如

def update(index: Int, value: String) { ... }

然后将其称为

foo(i) = "Text"

是否存在封装该特征的特征?像

这样的东西
trait Update1[+A,+B] {
    def update(i: A, v: B)
}

(当然我可以自己定义这样的特性,但它只适用于我与之混合的实例,而不适用于超出我影响的其他实例。)

1 个答案:

答案 0 :(得分:1)

您无法定义此类特征的原因是您在不允许的地方使用协变类型参数。以下特征在Scala 2.10中编译良好:

trait Update1[-A, -B] {
  def update(i: A, v: B) : Unit
}

trait MyFunction1[-A, +B] {
  def apply(a:A): B
}

trait Mutable[-A, B] extends Update1[A,B] with MyFunction1[A,B]

请注意,为了具有可变性状,您必须修复 B 参数,因此它既不允许协方差也不允许相反。如果您查看Scala API中的可变集合,您可以看到实际上这是它们的声明方式。

此外,如果您知道该类已经实现了特征中定义的方法,那么没有什么可以阻止您在对象而不是类中混合特征以使编译器满意。例如,您可以拥有以下内容:

class SingleStringCollection(v: String) extends MyFunction1[Int, String] {
  private var someString: String = v
  def apply(a: Int): String =  someString

  def update(i: Int, v: String): Unit = {
    someString = v
  }
  override def toString = someString
}

val test1: Update1[Int, String] = new SingleStringCollection("hi") // this would fail
val test2: Update1[Int, String] = new SingleStringCollection("hi") with Update1[Int, String] // this would work

如果您只是想要求val或参数实现已知方法的列表,您也可以使用结构类型:

type UpdatableStructuralType = {
  def update(i: Int, v: String) : Unit
}

val test3: UpdatableStructuralType = new SingleStringCollection("hi") // this would work
test3(0) = "great" // And of course this would also work

如果您想接受符合某些特征的参数或需要实施某些方法,那么您有几种选择。