Scala那些奇怪的符号(三)“

时间:2021-12-08 06:29:29

<%

      这个符号有点像“<:”,但作用却完全不一样,类型上边界“<:”的意思有点像继承,A <: B 表示 A是B的子类;而A <% B的意思是“A可以转化为B”,这里可以不必强调A和B本身的关系,只要有一个从A到B的隐士转化即可。(注意:不必是隐士转换,因为可能是B类本身)下面我们看例子:

依然是上几篇文章中的那几个例子,有Earth、Anima、Bird三个类,三者之间的关系是:Bird继承于Animal,Animal继承于Earth

class Earth {
def sound(){
println("hello !")
}
}

class Animal extends Earth{
override def sound() ={
println("animal sound")
}
}

class Bird extends Animal{
override def sound()={
print("bird sounds")
}
}

然后我们定义一个函数:

def biophony[T <% Animal](things: T) = {
things.sound()
}

然后调用此方法:

biophony(new Earth)

输出结果:


Scala那些奇怪的符号(三)“

它说得要一个从Earth到Animal的隐士转化,我们给它加上:

implicit def autoChange(things:Earth) = new Animal

运行:


Scala那些奇怪的符号(三)“

成功!

我们讲到 A <% B,A和B可以没有父子关系,于是:

implicit def autoChange(things:String) = new Animal

def biophony[T <% Animal](things: T) = {
things.sound()
}

调用:

biophony(new String)

输出:

Scala那些奇怪的符号(三)“

成功!

A<%B 原来可以当B 直接用!和传个B类型的参数没有区别,那么,我们真传一个B,还用类型转化吗?咱们把类型转化去掉。

def main(args: Array[String]) {
biophony(new
Animal)
}

// implicit def autoChange(things:String) = new Animal

def biophony[T <% Animal](things: T) = {
things.sound()
}

运行,输出:

Scala那些奇怪的符号(三)“

看来,如果直接传过需要转化成的参数类型,就不必做类型转化了。

A:B

 上下文边界。在这里,不同于传参的A:B,在这里的意思是:必须存在一个“B[A]”的隐士值。

定义一个函数:

def biophony[T:Seq](things: T) = {
println("hello world")
}

如果直接调用:

def main(args: Array[String]) {
biophony(new Animal)
}

输出:

Scala那些奇怪的符号(三)“


缺少B[A]的隐士参数,我们给它加上一个,然后调用:

implicit val b = Seq(new Animal)
biophony(new Animal)
成功!


"A <% B"和“A:B”都是和隐士转化有关,“A <% B”是有A到B的隐士转化,“A:B”是有B[A]的隐士参数。