scala中的类型安全的respond_to可能吗?

Deb*_*ski 4 casting scala case typechecking respond-to

使用用于类型安全铸造的案例构造很容易在scala中完成.以下代码确保square仅在具有相应类型的对象上调用.

class O
class A extends O {
    def square(i: Int):Int = { i*i }
}
class B extends O {
    def square(d: Double):Double = { d*d }
}
class C extends O {}

def square(o: O) = o match {
    case a:A => print(a.square(3))
    case b:B => print(b.square(3.0))
    case c:C => print(9)
    case _ => print("9")
}
Run Code Online (Sandbox Code Playgroud)

另一方面,存在这样的情况:使用用于铸造的类型信息并不那么容易,并且仅检查a的可用性{def square(Int): Int}就足够了.scala中是否有一个允许执行类似操作的构造

def square(o: O) = o match {
    case a:{def square(Int):Int} => print(a.square(3))
    case b:{def square(Double):Double} => print(b.square(3.0))
    case _ => print("9")
}
Run Code Online (Sandbox Code Playgroud)

使用隐式证据参数,可以根据其他方法的可用性定义方法.是否也可以在定义它们时调用它们?

Ran*_*ulz 5

结构类型表示成员的非继承约束可用性,因此如果您希望方法只接受带有特定方法的值def square(i: Int): Int,请使用以下表示法:

class Squaring {
  type Squarable = { def square(i: Int): Int }
  def squareMe(s: Squarable): Int = s.square(17)
}

class CanSquare { def square(i: Int) = i * i }

val cs1 = new CanSquare
val s1 = new Squaring

printf("s1.squareMe(cs1)=%d%n", s1.squareMe(cs1))


s1.squareMe(cs1)=289
Run Code Online (Sandbox Code Playgroud)

您应该知道结构类型是通过反射实现的,但是从Scala 2.8开始,反射信息在逐个类的基础上缓存在调用站点上(实际提供的值类).