scala 中是否存在非类型模板参数?

Do non-type template parameters exist in scala?

是否可以在 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中呢? 如果他们不这样做,还有其他方法可以做我想做的事吗?

看来你只是想定义自定义 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 将匹配第一个模式,AtvCar 将匹配第二个模式,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()

假设 C++ 中的值泛型是指 non-type template parameters, Scala doesn't support them directly but can do some of the same things with singleton types, especially in 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]() = ...