Scala那些奇怪的符号(三)“<%” 和 “:”

<%

      这个符号有点像“<:”,但作用却完全不一样,类型上边界“<:”的意思有点像继承,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)

输出结果:



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

implicit def autoChange(things:Earth) = new Animal

运行:



成功!

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

implicit def autoChange(things:String) = new Animal

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

调用:

biophony(new String)

输出:


成功!

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()
  }

运行,输出:


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

A:B

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

定义一个函数:

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

如果直接调用:

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

输出:



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

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


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章