Scala:在单例类型上“泛化”?

tjrkku2a  于 6个月前  发布在  Scala
关注(0)|答案(3)|浏览(55)

在Scala中,值和对象都有单独分配给它们的单例类型。所以我们可以有:

val x = 1
type X = x.type
val y = 2
type Y = y.type

字符串

  • 我可以写一个只接受x作为参数的方法吗?

我试探着:

val x = 1
def foo(i: x.type ) = println(x.toString)


但是它给了我一个错误。我想它是在抱怨类型未知的事实。有没有一种方法可以指定i应该是一个int,这样我们就可以在上面使用.tofloat

  • 上面的XY,即12的单例类型,是否有一个共同的祖先,所以我可以编写一个泛型代码,涉及Int值的单例类型。
  • 同样地,

如果我举个例子

val list = [1,2,3]


有没有一种方法可以编写一个代码,对这些值进行泛化,并且只能输入其中一个值?

to94eoyn

to94eoyn1#

在Python 2.12.5中,它只适用于装箱的非原始整数:

val x: java.lang.Integer = 42
def foo(i: x.type): Unit = println(i.toFloat)

字符串
我不知道为什么它不适用于val x: Int。在Dotty中,它也适用于原始类型:

val x: Int = 42
def foo(i: x.type): Unit = println(x.toFloat)


对于多个值(列表),你可以使用枚举,或者简单地创建一个带有私有构造函数的小类,并在同伴类中示例化所有有效值:

class SmallInt private(value: Int) {
  def asFloat = value.toFloat
}

object SmallInt {
  val one = new SmallInt(1)
  val two = new SmallInt(2)
  val three = new SmallInt(3)
}


这样就不会编译了:

val foo = new SmallInt(345678) // forbidden

krugob8w

krugob8w2#

我写了一个只接受x作为参数的方法?
如果它只能接受一个参数,那么它就不需要

val x = 1
def f() = println(x.toString)

字符串
上面的X和Y,也就是1和2的单例类型,是否有一个共同的祖先,所以我可以写一个泛型代码,涉及Int值的单例类型......
我不明白。让函数接受一组任意类作为输入的一种方法是使用隐式转换

trait CanUse{
    def use(): Int
}

def f[A](a: A)(implicit cvt: (A) => CanUse): Int = cvt(a).use() + 1


然后为每个可接受的输入类型定义隐式转换器

implicit class UsableInt(i: Int) extends CanUse{
   def use() = i
}

mcdcgff0

mcdcgff03#

Scala 2.13解决了这个问题:D
https://scastie.scala-lang.org/T637W491Sl2gN50ZVWAvBQ

val x = 1
type X = x.type
val y = 2
type Y = y.type

字符串

相关问题