Scala: два метода, разные типы параметров, но один и тот же код: как объединить? - PullRequest
4 голосов
/ 31 мая 2009

У меня есть следующие классы:

case class Vec2(x: Int, y: Int) { def +(other: Vec2) = Vec2(x + other.x, y + other.y) }
case class Vec3(x: Int, y: Int, z: Int) { def +(other: Vec3) = Vec3(x + other.x, y + other.y, z + other.z) }

И следующие методы:

def doStuff1(a: Vec2, b: Vec2) = (a, a + b)
def doStuff2(b: Vec3, b: Vec3) = (a, a + b)

Мой вопрос: как я могу объединить эти две функции в одну универсальную безопасным для типов образом? Классы могут быть изменены любым способом.

Что-то вроде

def doStuff[V](a: V, b: V) = (a, a + b)

, очевидно, не будет работать из-за вызова метода "+". Я перепробовал все виды сумасшедших вещей (общий базовый класс с абстрактным типом, явно типизированные собственные ссылки, дисперсии, ...), но не смог найти решение.

Лучшая идея, которую я мог бы придумать, - это проверка во время выполнения (сопоставление с образцом или isInstanceOf / asInstanceOf), но она не удовлетворяет требованию безопасности типов. Я просто думаю / надеюсь, что должен быть лучший способ сделать это.

Ответы [ 2 ]

20 голосов
/ 31 мая 2009
trait Vector[V <: Vector[V]] { this: V =>
  def +(other: V): V
}

case class Vec2(x: Int, y: Int) extends Vector[Vec2] {
  override def +(other: Vec2): Vec2 = Vec2(x + other.x, y + other.y)
}

case class Vec3(x: Int, y: Int, z: Int) extends Vector[Vec3] {
  override def +(other: Vec3): Vec3 = Vec3(x + other.x, y + other.y, z + other.z)
}

def doStuff[V <: Vector[V]](a: V, b: V): (V, V) = (a, a + b)
0 голосов
/ 03 января 2013

Вы можете попробовать какой-нибудь тип конструкции . Как это:

def doStuff[V <: {def +(other: V): V }](a: V, b: V) = (a, a + b)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...