Существуют ли нетипичные параметры шаблона в scala? - PullRequest
0 голосов
/ 07 апреля 2020

Возможно ли иметь значение дженериков в scala? То есть дженерики, которые являются не типом, а значением. Я хотел бы, чтобы они выглядели примерно так: class Animal[legs: Int], но он не компилируется.

Мне удалось заставить это скомпилироваться, но я не уверен, что компилятор понимает это так же, как я.

abstract sealed class WheeledVehicle(wheels: Int)
case object Motorcycle extends WheeledVehicle(2)
case object Atv extends WheeledVehicle(4)
case object Car extends WheeledVehicle(4)
case object Truck extends WheeledVehicle(6)

Более того, мне не удалось сопоставить значение vehicle.

vehicle match {
    case _: WheeledVehicle(2) => useTwoWheels()
    case _: WheeledVehicle(4) => useFourWheels()
    case _: WheeledVehicle(6) => useSixWheels()
}

Обобщения значений существуют в некоторых других языках, таких как C ++. Но как насчет scala? А если нет, есть ли другой способ сделать то, что я хотел бы сделать?

Ответы [ 2 ]

4 голосов
/ 07 апреля 2020

Похоже, вы просто хотите определить custom unapply

abstract sealed class WheeledVehicle(val wheels: Int)
object WheeledVehicle {
  def unapply(arg: WheeledVehicle): Option[Int] = Some(arg.wheels)
}

vehicle match {
  case WheeledVehicle(2) => useTwoWheels()
  case WheeledVehicle(4) => useFourWheels()
  case WheeledVehicle(6) => useSixWheels()
}

Motorcycle будет соответствовать первому шаблону, Atv и Car будут соответствовать второму, Truck будет соответствовать третий.

Или

abstract sealed class WheeledVehicle(val wheels: Int)

vehicle match {
  case w: WheeledVehicle if w.wheels == 2 => useTwoWheels()
  case w: WheeledVehicle if w.wheels == 4 => useFourWheels()
  case w: WheeledVehicle if w.wheels == 6 => useSixWheels()
}

или

vehicle match {
  case _ if vehicle.wheels == 2 => useTwoWheels()
  case _ if vehicle.wheels == 4 => useFourWheels()
  case _ if vehicle.wheels == 6 => useSixWheels()
}

или

if (vehicle.wheels == 2) useTwoWheels()
else if (vehicle.wheels == 4) useFourWheels()
else if (vehicle.wheels == 6) useSixWheels()
else useDefault()
2 голосов
/ 07 апреля 2020

Предполагая, что в качестве универсальных значений в C ++ вы имеете в виду нетипизированные параметры шаблона , Scala не поддерживает их напрямую, но может делать то же самое с одиночными типами, особенно в Scala 2.13 :

class Animal[Legs <: Int with Singleton]

val x = new Animal[10]

или если вам нужен доступ к значению

class Animal[Legs <: Int with Singleton](implicit v: ValueOf[Legs]) {
  def legs = v.value
}

val x = new Animal[10]
println(x.legs)

Невозможно сопоставить шаблон с Animal[10] против Animal[4], но тогда вы тоже не сможете сделать это для List[String] против List[Int]. Что вы можете сделать, это передать параметр, например:

def f[N <: Int with Singleton](vehicle: WheeledVehicle[N]) = useNWheels[N]()

def useNWheels[N <: Int with Singleton]() = ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...