日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变

發布時間:2024/3/13 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.前言:

學過java我們都知道,java中的繼承是對類的增強,java中的代理、裝飾是對對象方法的增強。而在scala中,隱式轉換和隱式參數是Scala中兩個非常強大的功能,隱式的對類的方法進行增強,豐富現有類庫的功能 。利用隱式轉換和隱式參數,你可以提供優雅的類庫,對類庫的使用者隱匿掉那些枯燥乏味的細節。

而所謂的隱式轉化函數,是指那種以implicit關鍵字聲明的帶有單個參數的函數。在了解隱式參數及轉換之前,有必要提及一下柯里化。下面,我會通過文字與代碼相結合的方式供大家更好的理解這些概念及入門使用,謬論之處歡迎指正!

2.柯里化

在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數且返回結果的新函數的技術。

更直觀的對比:

def m1(x:Int,y:Int)=x+y?????? m1(2,3)??? =5? 正常方法

def m2(x:Int)(y:Int)=x+y???? m2(2)(3)??? =5?? 柯里化

至于柯里化的好處請參考:http://blog.csdn.net/wangguohe/article/details/79007737

3.隱式參數

package lesson11/*隱式的都是要放在object里面,因為都是直接調用的,而不是去new的*/ object Test {def k1(x:Int)(y:Int):Int= x+ y//implicit 隱式的//先找 全局 里面是否 有 int 類型的隱式值//如果有就要全局里面的,如果沒有就看局部的,局部有就要局部的//如果局部沒有就報錯了。//全局只能有一個隱式參數滿足條件,多個條件如果都滿足,那么就會報錯implicit val xiaoma:Int=10 // implicit val xiaoma2:Int=9def k2(x:Int)(implicit y:Int=6)= x * ydef main(args: Array[String]): Unit = { // val kresult = k1(5)(6) 30val kresult = k2(8)println(kresult) //80}}

4.隱式轉換

情景一:當某個對象去調用某個方法的時候,如果這個對象沒有這個方法,就會發生隱式轉換。

案例1:man是沒有fly的功能,但是通過隱式轉換,將Man對象轉換為了SuperMan的對象,他可以調用此功能。

package lesson13class Man {} class SuperMan{def fly(){println("超人會飛")} } object Test{implicit def man2Superman(man:Man):SuperMan=new SuperMan()def main(args: Array[String]): Unit = {val man = new Man()man.fly()} } 案例2:File本身是沒有read功能的,但是通過隱式轉換,將File對象轉換為RichFile對象,他也調用了read功能。 package lesson12import java.io.File import scala.io.Source object Test {def main(args: Array[String]): Unit = {implicit def file2RichFile(file:File):RichFile=new RichFile(file)val file = new File("D:\a.txt").read()println(file)} } class RichFile(f:File) {def read():String={Source.fromFile(f).mkString} } 可以發現以上兩種案例的區別就是第一個轉換時沒有將自己作為轉換后的類的參數,而第二個file則作為了參數。

思考1?我們用過1 to 10,其本質是 1.to(10), 1 是自動匹配為Int類型,那Int有to方法嗎?實現Int有to方法的方式又是怎樣的呢?? (implicit def intWrapper(x: Int)? = new runtime.RichInt(x))

思考2?有沒有發現隱式轉換與java的那個設計模式比較像呢?(裝飾者模式)


情景二:某個對象去調用某個方法,這個對象也確實有這個方法,只不過傳入的參數類型不匹配,就會發生隱式轉換。

案例3:買票方法buySpecialTicket傳入的參數是特殊人群SpecialPerson,但是調用的時傳入的參數不是SpecialPerson類型。

package lesson14//定義了一個類: 代表的是特殊人群 class SpecialPerson(var name:String){} //學生 class Student(val name:String){} //老人 class Older(val name:String){} //一般的普通人 class Worker(val name:String){}class TicketHouse{var num:Int=1;def buySpecialTicket(p:SpecialPerson)={num+=1println("T-"+ num )}}object Test{ implicit def object2SpecialPerson(obj: Object):SpecialPerson={if(obj.getClass == classOf[Student]){ //判斷這個對象是不是學生val student = obj.asInstanceOf[Student]new SpecialPerson(student.name)}else if(obj.getClass == classOf[Older]){val older = obj.asInstanceOf[Older]new SpecialPerson(older.name)}else{None}}def main(args: Array[String]): Unit = {val house = new TicketHouse()val worker = new Worker("jianglaoshi")val student = new Student("xiaoma")val older = new Older("wukong")house.buySpecialTicket(older)} } 情景三:視圖邊界? A <% B

?A <% B? 左側必須是右側的子類, 如果A 不是B的子類,這個時候也會發生隱式轉換,把A 轉換成為 B。

案例4:本來有個方法人只能跟人交朋友,人也想跟狗交朋友,把夠隱式轉換成為人。

class Person(var name:String) {def sayHello=println("hello ,I'm "+ name)def makeFriends(p:Person): Unit ={sayHellop.sayHelloprintln("我們就是好朋友")} }class Student(name:String) extends Person(name) class Dog(var name:String)class Worker(val name:String)class Party[T <% Person](p1:T,p2:T){def play(): Unit ={p1.makeFriends(p2)} }object Test{ implicit def dog2Person(obj:Object):Person={if(obj.isInstanceOf[Dog]){val dog_ = obj.asInstanceOf[Dog]new Person(dog_.name)}else {None}}def main(args: Array[String]): Unit = {val sunli = new Student("孫儷")val zhouxu = new Student("周迅")val dog = new Dog("哮天犬")val worker = new Worker("malaoshi") val party = new Party[Person](sunli,dog)party.play()}} 接下來,我們要講到的上界、下界、協變、逆變就結合隱式轉換來進行理解。

5.上界、下界、協變、逆變

上界:T <: ...?? T 是...的類型或子類

案例5:比顏值。

package lesson15class Pair[T <:Comparable[T]] {def shuai(first:T,second:T):T={if(first.compareTo(second) > 0) first else second} }object Test{def main(args: Array[String]): Unit = {val pair = new Pair[Boy]val shuai = pair.shuai(new Boy("段奕宏",99),new Boy("王千源",88))print(shuai)} } class Boy(var name:String,var faceValue:Int) extends Comparable[Boy]{override def compareTo(o: Boy): Int = {(this.faceValue - o.faceValue)}override def toString: String = {s"name:${name} value:${faceValue}"} } 下界:T >: ...?? T是...的類型或父類。

案例6:取身份證,定義了下界Child,?GrangFather Father 能取走我的身份證。

class GrandFather class Father extends GrandFather class Child extends Fatherclass Tongshiobject Test{def getIDCard[T >: Child](person:T): Unit ={println("好的,身份證就交給你了!!")}def main(args: Array[String]): Unit = {getIDCard[GrandFather](new GrandFather)} }
協變:本來要的是父類,但是子類來了也可以。

逆變:本來來的是子類,但是父類來了也可以。

由于概念非常簡單,這里直接上代碼取體會。

案例7:

class QingTong class BaiJin extends QingTong class WangZhe extends BaiJin class Worker//協變 class Card[+T](val name:String)object Test{def daSai(card:Card[QingTong]): Unit ={println("歡迎參加王者榮耀大賽")}def main(args: Array[String]): Unit = {val c1 = new Card[QingTong]("malaoshi")val wangzhe = new Card[WangZhe]("jianglaoshi")// val jia = new Card[Worker]("lurenjia")// daSai(wangzhe)} } 案例8: class Master class Professinal extends Master class Studentclass Card[-T](val name:String)object Test{def shangHaiDaShiSai(card:Card[Professinal]): Unit ={println("歡迎你來到上海大師賽")}def main(args: Array[String]): Unit = {val lc = new Card[Professinal]("梁文博")val ac = new Card[Master]("奧沙利文")val student = new Student// shangHaiDaShiSai(student)} }












?










總結

以上是生活随笔為你收集整理的7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。