Как использовать объекты-компаньоны в качестве стратегии? - PullRequest
1 голос
/ 25 октября 2011

У меня есть тест, который периодически дает сбой из-за проблем с упорядочением, когда я перебираю значения в Map.

. В Scala полезно предоставить ListMap, который делает тесты стабильными за счет производительности.,Поэтому я абстрагировал ImmutableMapFactory в качестве значения val и использовал его в своем коде.

class C {
  val immutableMapFactory = scala.collection.immutable.Map

  def func = {
    ...
    immutableMapFactory(pairs :_*)
  }
}

Теперь я планировал расширить C и переопределить immutableMapFactory для тестов

class TestableC extends C {
  override val immutableMapFactory = scala.collection.immutable.ListMap
}

Неудивительноэто терпит неудачу, поскольку ListMap не имеет тот же тип, что и Map.Как мне указать тип val (или def), чтобы я мог использовать фабрику везде, где мне нужно создать карту?

Ответы [ 2 ]

3 голосов
/ 25 октября 2011

Два возможных способа.Во-первых, используя def и функции, которые я считаю лучшей абстракцией.

class C {
  def immutableMapFactory[A,B]: ((A,B)*) => Map[A,B] = scala.collection.immutable.Map.apply _
}

class TestableC extends C {
  override def immutableMapFactory[A,B] = scala.collection.immutable.ListMap.apply _
}

Во-вторых, используя val и структурные типы:

class C {
  val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.Map
}

class TestableC extends C {
  override val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.ListMap
}
2 голосов
/ 25 октября 2011

Ваша проблема в этой строке:

val immutableMapFactory = scala.collection.immutable.Map

Это делает immutableMapFactory равным одноэлементному объекту Map.ListMap (синглтон) - это , а не подкласс Map (синглтон), поэтому последующее переопределение завершится неудачей.

Если вместо этого вы взяли метод apply из Map и частично примените его для формирования функции первого класса (типа (A, B)* => immutable.Map[A,B]), после чего метод можно заставить работать:

import collection.immutable

class Bip {
  def fac[A,B] = immutable.Map.apply[A,B] _
}

class Bop extends Bip {
  override def fac[A,B] = immutable.ListMap.apply[A,B] _
}
...