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]的隱士參數。 

更多精彩內容,請關注我的微信公衆賬號 互聯網技術窩

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