日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scala编程指南

發(fā)布時(shí)間:2023/12/4 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala编程指南 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.scala簡介

2004年,martin ordersky發(fā)明,javac的編譯器,后來spark,kafka應(yīng)用廣泛,twitter應(yīng)用推廣。它具備面向?qū)ο蠛秃瘮?shù)式編程的特點(diǎn)。 官網(wǎng):www.scala-lang.org,最近版本2.12.5,我們用的是2.10.4

2.環(huán)境安裝

1) windowsa) 安裝jdk-7u55-windows-x64.exeb) 安裝scala-2.10.4.msi安裝完以上兩步,不用做任何修改。測試:在控制臺下c:/>scalac) 安裝eclipse-java-juno-SR2-win32-x86_64.zip 解壓縮即可d) 安裝eclipse的scala插件update-site.zip解壓會有兩個(gè)目錄,features和plugins,分別把內(nèi)容放到eclispe對應(yīng)的目錄下。 e) 重啟eclipse提示"Upgrade of scala...",點(diǎn)yes提示框"setup Diagnostic",把Enable JDT weaving...選上根據(jù)提示重啟 2) linux

3.第一個(gè)程序

1) 交互式編程C:\Users\Administrator>scalaWelcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_5Type in expressions to have them evaluated.Type :help for more information.scala> 1+1res0: Int = 22) 腳本形式:通過創(chuàng)建文件來在eclipse/idea中執(zhí)行代碼object Test {def main(args: Array[String] ) {println("Hello world")}}注1:上面這個(gè)是單例對象,這個(gè)里面只能存放靜態(tài)的東西注2:自動(dòng)導(dǎo)入2個(gè)包java.lang._scala._注3:語句最后一行的分號不推薦寫

4.基礎(chǔ)語法

1) 變量和常量

val(常量)和var(變量) 盡可能的用val(1) 變量格式:var 變量名 [:數(shù)據(jù)類型] = 值例:var b :Int = 1var c = 2 //類型自動(dòng)推斷(2) 常量格式:val 常量名 [:數(shù)據(jù)類型] = 值例:val b :Int = 1val b = 1b = 2 //報(bào)錯(cuò),常量不能修改(3) 常量可以用lazy修飾(了解)lazy val b :Int = 1 //b用到的時(shí)候再賦值

2) 數(shù)據(jù)類型

(1)數(shù)據(jù)類型序號 數(shù)據(jù)類型 說明1 Byte 8位有符號值,范圍從-128至1272 Short 16位有符號值,范圍從-32768至327673 Int 32位有符號值,范圍從-2147483648至21474836474 Long 64位有符號值,范圍從-9223372036854775808至92233720368547758075 Float 32位IEEE 754單精度浮點(diǎn)值6 Double 64位IEEE 754雙精度浮點(diǎn)值7 Char 16位無符號Unicode字符。范圍從U+0000到U+FFFF8 String 一個(gè)Char類型序列9 Boolean 文字值true或文字值false10 Unit 對應(yīng)于無值,等價(jià)于void類型,只有一個(gè)對象叫()11 Null 只有一個(gè)對象叫null12 Nothing 在Scala中處于最底層,比如創(chuàng)建數(shù)組時(shí)不指定類型,就是Noting。抽象概念13 Any 任何類型的超類型; 任何對象的類型為Any14 AnyRef 任何引用類型的超類型(2)層次結(jié)構(gòu)Scala.Any-AnyVal(值)-Int,Double等,Unit。-AnyRef(引用)-List,Set,Map,Seq,Iterable-java.lang.String-Null(3)重點(diǎn)類型:元組格式:(元素1, 元素2, ....)訪問:變量._N 其中N是元組元素的索引,從1開始例:var t = ("a", false, 1) //t的類型是scala.Tuple3var value = t._1 //"a"var m,n,(x,y,z) = ("a", false, 1) m :("a", false, 1) n :("a", false, 1)x : 'a'y : false:z : 1(4)重點(diǎn)類型:字符串i) 用的是java.lang.String,但是有時(shí)候根據(jù)需要,會隱式轉(zhuǎn)換到其它類型,比如調(diào)用reverse/sorted/sortWith/drop/slice等方法,這些方法定義在IndexedSeqOptimized中ii)多行字符串表示,開始和結(jié)束用(4)重點(diǎn)類型:字符串i)用的是java.lang.String,但是有時(shí)候根據(jù)需要,會隱式轉(zhuǎn)換到其它類型,比如調(diào)用reverse/sorted/sortWith/drop/slice等方法,這些方法定義在IndexedSeqOptimized中ii)多行字符串表示,開始和結(jié)束用(5)了解:符號類型符號字面量: '標(biāo)識符,是scala.Symbol的實(shí)例,像模式匹配,類型判斷會比較常用。var flag = 'startif (flag == 'start) println(1) else println(2)

3) 運(yùn)算符:scala沒有運(yùn)算符,它運(yùn)算符全部封裝成了方法。

算術(shù):+ - * / %比較: == != > < >= <= 邏輯:&& || !賦值:= += -= *= /* %=位:& | ~ ^ >> << >>> #*/注:上面都是方法。例 1+2相當(dāng)于1.+(2),其中+是方法,2是參數(shù)

4) 控制語句

(1) if,if...else...,if...else if...else...(2) scala中的if可以作為表達(dá)式用var x = if("hello"=="hell") 1 else 0(3) switch被模式匹配替換

5) 循環(huán)語句

(1)while,do..while和for都有,while和do..while很像,但是for差別很大。(2)for循環(huán)格式不同for(變量 <- 集合 if 條件判斷1;if 條件判斷2...) {所有條件判斷都滿足才執(zhí)行}(3)沒有break和continue,用兩種方法可以代替i) 用for循環(huán)的條件判斷ii)方法2:非寫break,要做以下兩步//1) 引入一個(gè)包scala.util.control.Breaks._//2) 代碼塊用breakable修飾breakbreakable {for(i<-0 to 10) {println(i)if (i == 5) {break;}}}//0 1 2 3 4 5continuefor(i<-0 to 10) {breakable {if (i == 3 || i==6) {break;}println(i)}}//0 1 2 4 5 7 8 9 10(5) 集合框架(Array,List,Set,Map)在scala中,數(shù)組Array歸到集合的范疇包scala.collection,下面有兩個(gè)分支immutable(不可改變的,默認(rèn))和mutable(可變的)(1) 層次結(jié)構(gòu)Traversable-Iterable(immutable不可改變的長度,默認(rèn))-Set 無序的集合,沒有重復(fù)元素HashSet,TreeSt 其中HashSet內(nèi)部定義了別名Set-Map 鍵值對,映射HashMap,TreeMap 其中HashMap內(nèi)部定義了別名Map-Seq 序列。有先后順序的元素集合-IndexedSeqArray:有索引的元素序列,因此可以通過下標(biāo)訪問Vector,String,Range-LinearSeqList:線性的元素序列。訪問第1個(gè)元素,head方法,最后1個(gè)tail方法Queue,Stack(mutable可變的長度)-SetHashSet 其中HashSet內(nèi)部定義了別名Set-MapHashMap 其中HashMap內(nèi)部定義了別名Map-Seq-IndexedSeqArraySeq,StringBuilder-BufferArrayBuffer,ListBuffer-LinearSeqLinkedList,QueueStack重點(diǎn)記憶幾個(gè)不可變 可變Array ArrayBufferList ListBufferMap MapSet Set(2) 數(shù)組(非常重要):數(shù)據(jù)類型相同的元素,按照一定順序排序的集合。不可變數(shù)組 scala.Array可變長數(shù)組 scala.collection.mutable.ArrayBufferArray和ArrayBuffer1.Array創(chuàng)建var 變量名 = new Array[類型](長度) //var arr = new Array[Int](10)var 變量名 = Array(元素1,元素2,...) //var arr = Array(1,3,5,7),實(shí)際上是調(diào)用Array的方法apply取值:變量名(下標(biāo))2.ArrayBuffer創(chuàng)建var 變量名 = new ArrayBuffer[類型]() //var arr = new ArrayBuffer[Int]()var 變量名 = ArrayBuffer(元素1,元素2,...) //var arr = ArrayBuffer(1,3,5,7)3.共同方法sum 求和max 最大值min 最小值mkString(分隔符) 例:Array(1,3,5,7).mkString("|") //結(jié)果是1|3|5|7|9sorted 排序(從小到大)sortBysortWith 自定義排序reverse 翻轉(zhuǎn)toArray ArrayBuffer轉(zhuǎn)成ArraytoBuffer Array轉(zhuǎn)成ArrayBuffertoMap:如果Array內(nèi)部元素是對偶元組,可以轉(zhuǎn)成maptoList:轉(zhuǎn)成list4.ArrayBuffer的獨(dú)有方法+= 追加元素++= 追加集合trimEnd(n):刪除末尾n個(gè)元素insert(index,value1,value2,..valueN):第index的位置,插入value1,value2,...valueN)remove(index,n):第index個(gè)位置刪除n個(gè)元素clear():清空5.遍歷i) 通過下標(biāo)for (i <- 0 to 數(shù)組.length-1) {println(i)) //i表示數(shù)組的下標(biāo)}ii)直接取值for (e <- 數(shù)組) {println(e)}6.使用yield創(chuàng)建新數(shù)組var arr = for (i <- 數(shù)組) yield i * 27.多維數(shù)組var arr = Array(Array(元素1...),Array(元素,...)..)遍歷for (i <- arr) {for (j <- i) {println(j)}} (3) List(不可變)/ListBuffer(可變):List 和java.util.List不同,一旦創(chuàng)建不可以改變。一般做數(shù)據(jù)分析用List1.List定義//創(chuàng)建var list1 = List("aa","bb","ccc") //調(diào)用apply方法var list2 = List.apply("aa","bb","ccc"))//右操作符:當(dāng)方法名以:結(jié)尾時(shí),為右操作符,先做右邊//::右操作符,拼接元素,var list3 = "aa"::"bb"::"cc"::Nil //Nil是空集合,先做"cc"::Nil,其中::是Nil的方法var list4 = list1:::"dd"::Nil //:::拼接集合2.常用方法//查head() 第一個(gè)元素take(n) 取前n個(gè)元素tail() 除了第1個(gè)的全部元素init() 除了最后一個(gè)的全部元素//增:+和+: 前者是尾部追加元素,后者是在頭部追加元素,和::很像+=或append 追加元素(ListBuffer)++= 追加數(shù)組/列表(ListBuffer):: 追加元素(List)::: 追加數(shù)組/列表(List)//刪drop(n) 丟棄前n個(gè)元素//改 updated(index,value):用value地替換第index的位置的元素//其他isEmpty是否為空reverse 翻轉(zhuǎn)splitAt(m):把列表前m個(gè)做成一組,后面是一組flatten:以參數(shù)的列表作為參數(shù),把所有的元素連接到一起//toArray 轉(zhuǎn)成ArraytoArray 轉(zhuǎn)成Arrayzip:兩個(gè)List內(nèi)部的元素合并,返回結(jié)果是List,元素是對偶元組grouped(n):每n個(gè)元素分成1組,返回是迭代器Iterator,可以再用toList轉(zhuǎn)成list類型3.ListBufferimport scala.collection.mutable.ListBuffervar list5 = ListBuffer("111","222","333")(4) Set:不存在重復(fù)元素的集合如果用可變的,需要引入import scala.collection.mutable.Set//定義var s = Set(3.0, 1.0)//追加元素s += 2.0 //s = s + 2.0s += 2.0 //元素重復(fù),加不進(jìn)去(5) Map//定義var m1 = Map(("zhang3",20),("li4",23),("wang5",21)) //使用元組var m2 = Map(("zhang3"->20),("li4"->23),("wang5"->21))var m3 = Map[String,Int]() //定義空map,得用可變的才有意義。//添加和更新 var m = scala.collection.mutable.Map(("zhang3", 20), ("li4", 23), ("wang5", 21))m += (("zhao6", 22)) //m = m.updated("zheng7",19) //和上面方法一樣m.put("wu", 22) m ++= Map(("a" -> 1), ("b" -> 2))//刪除m -= (("zhao6", 22))m.clear() 清空//查詢m(key):通過key獲取valuem.get(key) :通過key獲取value,返回類型Optionm.getOrElse(key,獲取不到設(shè)置的值)//其它size:元素個(gè)數(shù)contains(key):是否包含key,返回布爾類型keys 返回迭代器keySet 返回所有的key組成的Set集合values 返回迭代器,所有value組成的集合mapValues(函數(shù))foreach(函數(shù))//遍歷(6) Array和List都是不可變元素,有什么區(qū)別?

5.函數(shù)

Scala中函數(shù)和方法,在類中定義的函數(shù)就是方法。

1) 函數(shù)聲明

def 函數(shù)名([參數(shù)列表]):[返回類型] = {函數(shù)體return [表達(dá)式]}注1:如果函數(shù)沒有返回值,可以返回Unit,也可以不寫注2:方法的返回類型可以不寫,系統(tǒng)自動(dòng)推導(dǎo),但是遞歸必須寫。注3:函數(shù)體的大括號只有一行,可以不寫例:def add(a:Int,b:Int):Int = {var sum : Int = 0sum = a + breturn sum}

2) 函數(shù)調(diào)用

格式:方法之間調(diào)用:函數(shù)名([實(shí)參列表]) 例:add(3,5)對象之間調(diào)用:實(shí)例名.函數(shù)名([實(shí)參列表]) 例:s.add(3,5)

3) 值函數(shù)

(1)定義var 變量名:[輸入類型=>輸出類型] = {(參數(shù)列表)=>{函數(shù)體}}其中=>是函數(shù)映射符在參數(shù)列表后不能寫返回值類型最后一句不能寫returnLambda表達(dá)式(匿名函數(shù),函數(shù)字面量):形如(參數(shù)列表)=>{函數(shù)體}就叫Lambda表達(dá)式

4) 高階函數(shù)

1) 定義:本身是函數(shù),參數(shù)也是函數(shù)或返回值是函數(shù)例1:def m(f:(Double)=>Double):Double = {f(100)}def sqrt(x:Double)=Math.sqrt(x)調(diào)用m(sqrt) 結(jié)果是10.02) 常見高階函數(shù)集合中常見的高階函數(shù)(1)map def map[B, That](f: A => B): That 把函數(shù)應(yīng)用于集合中的每一個(gè)元素,把返回由返回值組成的一個(gè)集合。例:Array("spark","hive","haddop").map((x:String)=>x.length)Array("spark","hive","haddop").map(x=>x.length)Array("spark","hive","haddop").map(_.length) // _占位符,代表一個(gè)元素Array("spark","hive","haddop").map(x=>println(x))Array("spark","hive","haddop").map(println _)Array("spark","hive","haddop").map(println) //如果只有一個(gè)參數(shù),可以不寫(2) flatMap把函數(shù)應(yīng)用于集合中的每一個(gè)元素,先做map,得到的結(jié)果flatten,生成新的集合。例:var list = List("a,b,c","d,e,f")var list2 = list.map(x=>x.split(",").toList) //List(List(a, b, c), List(d, e, f))list2.flatten //List(a,b,c,d,e,f)上面兩步可以寫成一步,相當(dāng)于map+flatternlist.flatMap(x=>x.split(",").toList) //簡寫:list.flatMap(_.split(",").toList)問:map和flatMap有什么區(qū)別?(3)filter參數(shù)的函數(shù)表示對集合的每個(gè)元素過濾,參數(shù)函數(shù)結(jié)果是boolean,最后的返回值還是ListList(1,2,3,4).filter(x=>x>2) //List(3,4)Array(1,2,3,4,5,6,7,8).filter(x=>x%2==0) //取偶數(shù) 2,4,6,8Range(1,100).filter(_%2==0) //1到100的偶數(shù)Array(1,2,3,4,5,6,7,8).filter(x=>x%2==0).map(_*10)//20,40,60,80注:filterNot和filter相反(4)reduce/reduceLeft/reduceRight返回1個(gè)值。參數(shù)函數(shù)要求是二元運(yùn)算符,作用于集合上,每次返回的結(jié)果作為新的輸入。Array(1,3,5,7).reduce((x,y)=>{println(x + ":" +y);x+y})Array(1,3,5,7).reduce(_+_) //第1個(gè)_代表第1個(gè)參數(shù),第2個(gè)_代表第2個(gè)參數(shù)Array(1,3,5,7).reduceLeft((x,y)=>{println(x + ":" +y);x+y})Array(1,3,5,7).reduceRight((x,y)=>{println(x + ":" +y);x+y})注:reduce沒有特別的順序,reduceLeft從左到右計(jì)算,reduceRigth從右到左計(jì)算(5)fold/foldLeft/foldRight和reduce很像,只是增加了一個(gè)初始值,但是做并行時(shí)要注意。Array(1,3,5,7).fold(4)(_+_) //20List(2.0,3.0).fold(4.0)(Math.pow) //4096.0(6) par把計(jì)算轉(zhuǎn)換為并行化,把reduce拆分多個(gè)任務(wù)Array(1,3,5,7,8).par.fold(4)(_+_)Range(1,10).par.map(println)(7) groupBy 對列表進(jìn)行分組,返回結(jié)果是mapvar data = List(("zhang3","male"),("li4","female"),("wang5","male"))data.groupBy(x=>x._2) //Map(male-> List((zhang3,male), (wang5,male)), female -> List((li4,female)))多介紹一個(gè)grouped(n):每n個(gè)分成一組例:List(1,3,5,7,9).grouped(2).toList //List(List(1, 3), List(5, 7), List(9))(8)partition把列表分成兩部分,第一個(gè)為滿足條件的,第二部為不滿足條件的List(1,3,5,7,9).partition(x=>x>4) //分成兩組:(List(5, 7, 9),List(1, 3))(9)diff差集,union并集并保留重復(fù),intersect交集var n1 = List(1,2,3)var n2 = List(2,3,4)var n3 = n1.diff(n2) //也可以寫n1 diff n2 ,結(jié)果:List(1)var n4 = n2.diff(n1) //List(4)var n5 = n1 union n2 //List(1 2 3 2 3 4)var n6 = n1 intersect n2 //List(2,3)(10)distinct去掉重復(fù)元素List(1,2,3,2,3,4).distinct // List(1, 2, 3, 4)(11)mapValues(函數(shù))還是map功能,只是處理的值是value,最終結(jié)果是mapMap(("zhang3",20),("li4",23),("wang5",21)).mapValues(_*2)//結(jié)果Map(zhang3 -> 40,li4 -> 46,wang5 -> 42)(12)foreach(函數(shù))和map一樣,區(qū)別是它沒有返回值,通常用在遍歷(13)sorted 排序和sortBy和sortWithsorted 排序,最簡單,從小到大List(2,1,3,5,6,4).sorted //1 2 3 4 5 6sortBy:按照第幾列排List(("a",3),("b",1),("c",2)).sortBy(_._2) //按照第2列排sortWith:自定義排序List(2,1,3,5,6,4).sortWith((x,y)=>x>y) //從大到小3)下劃線_的用法(1) 讓匿名函數(shù)更簡潔,可以用下劃線_當(dāng)做一個(gè)占位符。(2) java中導(dǎo)入包下的所有類用*,在scala中用_例:Java: import java.util.*scala: import java.util._(3) 下劃線_可以作為部分應(yīng)用函數(shù)4) 函數(shù)柯里化柯里化(curring) 把接收多個(gè)參數(shù)的函數(shù)編程接收一個(gè)單一參數(shù)例1:不是柯里化,但是和柯里化很像def foo(factor : Int) = (x:Double)=>factor * x;調(diào)用:var f = foo(10)f(50)也可以直接寫:foo(10)(50)例2:柯里化def foo(factor : Int)(x:Double) = factor * x調(diào)用:foo(10)(50)注:柯里化函數(shù)不是高階函數(shù),不能這么調(diào)用var f = foo(10)5)部分應(yīng)用函數(shù)(Partial Applied Function)部分應(yīng)用函數(shù), 是指一個(gè)函數(shù)有N個(gè)參數(shù), 而我們?yōu)槠涮峁┥儆贜個(gè)參數(shù), 那就得到了一個(gè)部分應(yīng)用函數(shù).,柯里化函數(shù)和普通函數(shù)都有部分應(yīng)用函數(shù)6)偏函數(shù)(Partial Function)(1)簡介引子:scala> List(1,2,3) map {case i:Int=>i+1}scala> List(1,2,3) map {(i:Int)=>i+1}上面兩個(gè)結(jié)果是一樣的。偏函數(shù):上面例子中map后面的被包在花括號內(nèi)的代碼,也就是沒有 match的一組case語句,就叫偏函數(shù)。偏函數(shù)類型是:PartialFunction[A,B],A的參數(shù)類型,B是返回結(jié)果類型。平常我們都是直接用。例1:val foo : PartialFunction[Int,String] = { //類型PartialFunction[Int,String]可以省略case y if y % 2 == 0 => y + " 是偶數(shù)"}println(foo(10)) //10 is Evenprintln(foo(11)) //拋出錯(cuò)誤: scala.MatchError----反編譯:相當(dāng)于foo是一個(gè)對象,調(diào)用對象的 apply方法private final PartialFunction foo = new PartialFunction{public final Object apply(int i){Object obj;if (i % 2 == 0)obj = y + " 是偶數(shù)"elseobj = i;return obj;}}foo.apply(10) (2)orElse:可以把多個(gè)偏函數(shù)結(jié)合起來,效果類似case語句。val or1 = {case 1 => "One"}val or2 = {case 2 => "Two"}val or_ = {case _ => "Other"}val or = or1 orElse or2 orElse or_ //使用orElse將多個(gè)偏結(jié)合起來//測試:scala> or(1) // one scala> or(20) //other(3) andThen: 相當(dāng)于方法的連續(xù)調(diào)用,比如g(f(x))。 val a = {case cs if cs == 1 => "One"}val b = {case cs if cs eq "One" => "The num is 1"}val c = a andThen b//測試num(1) //The num is 1(4) 普通函數(shù)的偏應(yīng)用函數(shù)定義比如我先定義一個(gè)函數(shù):def sum(a:Int,b:Int,c:Int) = a + b + c;那么就可以從這個(gè)函數(shù)衍生出一個(gè)偏應(yīng)用函數(shù)是這樣的:def foo = sum(1, _:Int, _:Int) 調(diào)用foo(2,3), 相當(dāng)于調(diào)用sum(1,2,3) 兩個(gè)_分別對應(yīng)函數(shù)sum對應(yīng)位置的參數(shù). 用處:當(dāng)你在代碼中需要多次調(diào)用一個(gè)函數(shù), 而其中的某個(gè)參數(shù)又總是一樣的時(shí)候, 使用這個(gè)可以少敲一些代碼(5)柯里化函數(shù)中的偏應(yīng)用函數(shù)定義def sum(a:Int)(b:Int)(c:Int) = a + b + c; // (a: Int)(b: Int)(c: Int)Intval result = sum _ //柯里化賦值,結(jié)果是部分應(yīng)用函數(shù) Int => (Int => (Int => Int)) = <function1>sum(1)(2)(3) //6result(1)(2)(3) //6result(1)(_: Int)(3) //部分應(yīng)用函數(shù):Int => Int = <function1>2018/4/5

1) 類和對象

(1) 簡介scala中的類和java中的類一樣,都是通過class定義class Person { //不寫public,默認(rèn)public//var name:String; //報(bào)錯(cuò),變量必須要被初始化,而java不需要被初始化,系統(tǒng)會自動(dòng)賦初值var name :String = null //正確var age :Int = _ //正確,不知道賦上面值時(shí),用_占位符}(2)創(chuàng)建對象var p1 = new Person()var p2 = new Person //沒有參數(shù),可以省略()(3) 類成員訪問p1.name = "zhang3" //設(shè)置,底層調(diào)用的是p1.name_=("zhang3"),其中_=是方法println(p1.name) //取值非要用getter和setter,屬性前加入 @BeanProperty(導(dǎo)入包:scala.beans._)(4) 單例對象scala中不支持靜態(tài)成員的語法,通過單例對象實(shí)現(xiàn)object Test {private var id:Int = 0def m() ={id += 1id}}測試:scala>Test.m //1scala>Test.m //2(5) 伴生對象和伴生類單例對象和類如果同名的話,單例對象也叫伴生對象。例:class A {}object A {}伴生對象和伴生類可以互相訪問,即使是private也可以訪問,但是private[this]不能訪問一個(gè)文件可以有多個(gè)類(6) apply方法object Dog {def apply():Unit = {println(1)}def apply(name:String):Unit = {println(2)}def main(args: Array[String]) { var d1 = Dog() //調(diào)用Apply()方法var d2 = Dog("hello") //調(diào)用Apply(String)方法}}

2) 主構(gòu)造方法

(1)定義每個(gè)類都有主構(gòu)造方法,參數(shù)放在類名后,構(gòu)造方法和類交織在一起。class Student(var name:String, var age:Int) 反編譯代碼:public class Student {private String name;private int age;public Student(String name, int age) {println("hello:" + name)this.name = name;this.age = age;}//getter和setter//name()和name_$eq(String)//age()和age_$eq(int)@Overridepublic String toString() {return name + ":" + age}} Student s = new Student();System.out.println(s) //打印s,就是打印s.toString()例:class Student(var name:String, var age:Int) {println("hello") //加在主構(gòu)造方法中override def toString = name + ":" +age}var s = new Student()println(s)(2) 帶有默認(rèn)參數(shù)的主構(gòu)造方法構(gòu)造方法可以帶有默認(rèn)參數(shù)。class Student(var name:String, var age:Int, val gender:String="female") {println("執(zhí)行主構(gòu)造方法")}var s1 = new Student("zhang3", 18, "male") //正確var s2 = new Student("li4", 18) //正確s2.name = "wang5"s2.gender = "male"(3) 私有構(gòu)造方法class Student private(var name:String, var age:Int)var s = new Student("li4", 18)//報(bào)錯(cuò)

3) 輔助構(gòu)造方法

(1) 非主構(gòu)造方法,方法名用this(2) 非主構(gòu)造方法,也可以有默認(rèn)值class Dog(val id:String) {var name :String = "大黃"def this(id:String,name:String) {this(id) this.name = name}override def toString = name + ":" + id}//測試var d1 = new Dog("1111")var d2 = new Dog("2222","二黃")println(d1)println(d2)

4) 繼承和多態(tài)

(1) 繼承用extendsclass Person(var name:String, var age:Int)//沒有寫var,表示繼承父類的屬性class Student(name:String,age:Int, var no:String) extends Person(name,age)//測試new Person("tom", 18)new Student("jack",19,"123")Student從父類繼承name和age,所以前面不要加變量var或者val,no是新加的元素,所以需要var(2) 多態(tài)多種形態(tài),動(dòng)態(tài)綁定,在執(zhí)行期間確定引用對象的實(shí)際類型,根據(jù)其實(shí)際類型調(diào)用相應(yīng)的方法,也就是子類可以賦值給父類。· class Human(var name:String, var age:Int) {def walk():Unit = {println("walk in Human")} }class Teacher(name:String,age:Int) extends Human(name,age) {override def walk():Unit = {println("walk in Teacher")} }class Doctor(name:String,age:Int) extends Human(name,age) {override def walk():Unit = {println("walk in Doctor")} }//測試var x:Human = new Teacher("tom", 18)var y:Human = new Doctor("jack", 19)x.walk //walk in Teachery.walk //walk in Doctor

5) 成員訪問控制

private 類內(nèi)+伴生對象protected 同包+子類不寫:默認(rèn)是public,都可以訪問特別之處(1) private[this] 只能類內(nèi)訪問class Person {private[this] var name:String = "zhang3" //只能類內(nèi)private var age: Int = 18 //類內(nèi)+伴生對象}object Person {def main(args:Array[String]) {var p = new Personprint(p.age) //18//print(p.name) //報(bào)錯(cuò)}}(2) 主構(gòu)造方法也可以加入成員訪問控制class Person(private var name:String, protected var age:Int)

6) 抽象類

不能能被實(shí)例化的類。可以有抽象方法,非抽象方法,成員變量。但是scala增加了抽象成員變量。abstract class Person {var name:String //抽象成員變量def walk //抽象方法}//子類如果繼承,必須要實(shí)現(xiàn)抽象變量和抽象方法,如果不想實(shí)現(xiàn),子類也需要是抽象類class Student extends Person {override var name:String = _ //覆蓋父類的抽象變量override def walk():Unit = {println("walk in Student")} //覆蓋父親的抽象方法}

7) 內(nèi)部類和內(nèi)部對象

定義在對象或者類內(nèi)部的類object Ex extends App {class Student(var name:String, var age:Int) { //內(nèi)部類class Grade(var name:String)//內(nèi)部對象object Utils {def print(name:String) = println(name)}}object Student {//內(nèi)部類class Printer {def print(name:String) = println(name)}}var s = new Student("tom", 18)//var grade = new Student.Grade("xxx") //此處出錯(cuò),怎么糾正?s.Utils.print("student:util.print(String)")new Student.Printer().print("Student.Printer().print(String)")}

8) 匿名類

沒有名字的類,一般用在某個(gè)類只在代碼出現(xiàn)一次abstract class Person(var name:String, var age:Int) {def print():Unit}//調(diào)用//var p = new Person("tom", 18) //錯(cuò)誤,抽象類不能new,也就是不能創(chuàng)建實(shí)例var p = new Person("tom", 18) {def print():Unit = println("hello")}p.print();

9) trait(特質(zhì)),其實(shí)就是接口,相當(dāng)于jdk1.8的接口,比jdk1.8以下版本的接口多了非抽象的變量和方法

(1) scala沒有提供接口interface,而用trait關(guān)鍵字,其實(shí)和接口等價(jià)。使用方法:extends或with,第一個(gè)實(shí)現(xiàn)的特質(zhì)用extends,之后的用with它和抽象基本一樣,可有抽象成員,抽象方法,具體成員和具體方法例:trait Closeable {def close():Unit}trait Clonable {def open():Unit}//第一個(gè)接口用extends,后面的用withclass File(var name:String) extends Closeable with Clonable{def close():Unit = println("file close")def open():Unit = println("file open")}//寫一個(gè)全的traittrait Book {var a : Long = _ //具體成員var b : Long //抽象成員def add(x:Int) //抽象方法def add2(x:Int):Int = x+2 //具體方法}var b = new Book(){ //定義匿名內(nèi)部類,只需要實(shí)現(xiàn)抽象方法和抽象成員變量即可override var b : Long = 1def add(x:Int) = println(x)}b.add(6)println(b.add2(5))

10) 自身類型(self type)

trait A {val a = 1}trait B {this:A=> //引入接口A,相當(dāng)于把A的東西全放進(jìn)來var b = 2def xx() {println(this.a + ":" + this.b)}}class C extends B with A//調(diào)用new C().xx()//還有一種特殊用法,this定義別名class D {self=> //為this定義別名self,也可以是其他名字var x = 2def foo = self.x + this.x}//常見用法,用在內(nèi)部類引用外部類的變量class OuterClass {xx=> //為this定義別名var value = "here"class InnerClass {println(xx.value)}}

7.包

1) 包定義

(1) 第一種定義方式,和java很像,package cn.cda.day1(2) 第二種定義方式package cn{package cda {package day1 {class Teacher {}}package day2 {class Student}}}以上方式不推薦

2) 作用域

scala中有private,proteced和默認(rèn)(public)外,還有private[x]和protected[x],其中x可以是包/類/單例對象

3) 包對象

通過package關(guān)鍵字聲明的對象為保對象,主要用于對常量和工具函數(shù)的封裝,通過包名引用。package object Math {val PI = 3.14}class Test {def main(args:Array[String]) {m(3) //3.14*9=28.62}def m(r:Double) = Math.PI * r * r}

4) import

導(dǎo)入包下的所有的類和對象,還可以引入重命名和類隱藏等功能。1) 隱式導(dǎo)入默認(rèn)導(dǎo)入的包,通過下面命令查看scala>:import2) 引入重命名import java.util.{HashMap=>JavaHashMap}import scala.collection.immutable.HashMapvar map = new JavaHashMap3) 類隱藏引入java.util.下的所有類,但是不想要HashMapimport java.util.{HashMap=>_,_} //隱藏HashMapimport scala.collection.immutable.HashMapvar map = new HashMap

8 模式匹配

1) 簡介

模式匹配類似switch語言,簡單用法就是替代多層的if else語句和類型檢查和快速匹配。它使用了關(guān)鍵字match來替換switch,一旦匹配到了,后面不再執(zhí)行,所以不用break語句。scala有一個(gè)十分強(qiáng)大的模式匹配機(jī)制,可以用到很多場合。如switch,類型檢查等,格式:case 變量: 類型=> 代碼例:java和scala進(jìn)行比較 --javafor (int i = 1; i < 5 ; i++) {switch (i) {case 1:System.out.println(1);break;case 2:System.out.println(2);//不帶break會陷入其它分支,同時(shí)輸出2,3case 3:System.out.println(3);break;default:System.out.println("default");//case語句不能接表達(dá)式//case i%5==0:System.out.println("10")}}--scalafor (i <- 1 to 5) {i match {case 1 => println(1) //不需要寫break,case 2 => println(2)case 3 => println(3) case _ => println("default")}}//上面的case語句中,還可以加入表達(dá)式for (i <- 1 to 5) {i match {case 1 => println(1) //不需要寫break,case x if (x%2 == 0) => println(s"$x 是偶數(shù)") //加入表達(dá)式 ,此時(shí)的x是形參,i是實(shí)參 case _ => //這句話表示其它任何情況都不進(jìn)行操作}}//還可以作為函數(shù)體def m(x:Int) = x match {case 5 => "整數(shù)5"case y if (y % 2 == 0) => "能被2整除" //注意y認(rèn)為是形參case _ => "其它整數(shù)"}println(m(5)//反編譯:public String m(int x){switch (x){default: tmpTernaryOp = "其它整數(shù)"; break;}return x % 2 == 0 ? "能被2整除" : "整數(shù)5";"}

2) 模式匹配的7大類型

(1)常量模式case后面接的全部是常量例:for (i <- 1 to 5) {i match {case 1 => println(1) //不需要寫break,case 2 => println(2)case 3 => println(3) case _ => println("default")//可以寫成 case x}}(2)變量模式case后面接的是變量例:def m(i:Int) = i match {case x if (x % 2 == 0) => "能被2整除" //這個(gè)順序是有關(guān)系的case x if (x % 3 == 0) => "能被3整除" case x => "能被2或3意外的數(shù)" // 等價(jià)于 case _}//調(diào)用println(m(5))println(m(4))println(m(3)) (3)構(gòu)造方法模式與創(chuàng)建對象相反,見下例1case class Dog(val name:String, val age:Int)def m(x:AnyRef) = x match {case Dog(name,age)=>println(name+":"+age)// 構(gòu)造函數(shù)模式,與創(chuàng)建對象相反,對對象進(jìn)行析構(gòu),調(diào)用unapply方法,普通類沒有,case類系統(tǒng)會生成。case _=>}//測試val dog = Dog("Pet", 2) //調(diào)用apply創(chuàng)建對象m(dog)例2:對部分變量析構(gòu)case class Dog(val name:String, val age:Int)def m(x:AnyRef) = x match {case Dog(_,age)=>println(age) //表示匹配這個(gè)成員域,但是不需要使用nam的值case _=>}(4)序列模式用于匹配Seq集合的,用法和上面類似,但是可以使用_*來匹配多個(gè)元素,并且只能放在模式內(nèi)的最后例:def m(x:AnyRef) = x match {case Array(a,b)=>println("1")case Array(a,_,b,_*)=>println("2") //_匹配第2個(gè)元素,_*匹配任意多,只能放模式最后case _=>}//調(diào)用 m(Array(1,2,3,4))(5)元組模式和上面用法相似,但是不能使用_*,_*只能在序列模式中使用。例:def m(x:AnyRef) = x match {case (a,b)=>println("1")case (a,_,b,_)=>println("2")//case (a,_*)//元素模式不能使用_*case _=>}var t = (1,2,3,4)m(t)(6)類型模式匹配變量的類型class Aclass Bclass C extends Adef m(x:AnyRef) = x match {case y:String=>println(1)case y:B=>println(2)case y:A=>println(3)case _=>println(4)}//測試val b = new Bval c = new Cm("hello")m(b)m(c)反編譯源代碼 public void m(Object x){if ((x instanceof String)){this.println(1);}else if ((x instanceof B)){this.println(2);}else if ((x instanceof A)){this.println(3);}else {this.println(4);}}(7)變量綁定模式如果想要的不是析構(gòu)對象,而且返回匹配模式的對象,很常用例1case class Dog(val name:String,val age:Int){override def toString=name+":"+age}def m(x:AnyRef) = x match { //Dog(_,_)用于匹配輸入對象中包括兩個(gè)成員變量的Dog對象,匹配成功后把對象賦值給dcase d@Dog(_,_) => println("變量綁定模式返回的變量值:" + d)case _=>}// 測試val dog = new Dog("Pet", 2)m(dog)反編譯源代碼:public void m(Object x) {if ((x instanceof Dog)){Dog d = (Dog)x;this.println("變量綁定模式返回的變量值:" + d)}else {}}例2:更常見,也更復(fù)雜val list = List(List(1,2,3,5),List(4,5,6,7,8,9))def m(x:AnyRef) = x match {//變量綁定模式case e1@List(_,e2@List(4,_*))=>println("e1:" + e1 + ",e2:" + e2)case _=>}//調(diào)用 m(list)//e1:List(List(1, 2, 3, 5), List(4, 5, 6, 7, 8, 9)),e2:List(4, 5, 6, 7, 8, 9)---反編譯代碼:public void m(Object x) { if ((x instanceof List)){List e1 = (List)x;Some localSome1 = List..MODULE$.unapplySeq(e1);if ((!localSome1.isEmpty()) && (localSome1.get() != null) && (((LinearSeqOptimized)localSome1.get()).lengthCompare(2) == 0)){Object e2 = ((LinearSeqOptimized)localSome1.get()).apply(1);if ((e2 instanceof List)){List localList2 = (List)e2;Some localSome2 = List..MODULE$.unapplySeq(localList2);if ((!localSome2.isEmpty()) && (localSome2.get() != null) && (((LinearSeqOptimized)localSome2.get()).lengthCompare(1) >= 0)){Object localObject2 = ((LinearSeqOptimized)localSome2.get()).apply(0);if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(4), localObject2)){Predef..MODULE$.println(new StringBuilder().append("e1:").append(e1).append(",e2:").append(localList2).toString());localBoxedUnit = BoxedUnit.UNIT; return;}}}}}}

3) 正則表達(dá)式與模式匹配(略)

(1)Scala正則表達(dá)式 (2)正則表達(dá)式在模式匹配中的應(yīng)用

4) for循環(huán)種的模式匹配

(1)變量模式匹配for((x,y)<-Map("a"->1,"b"->2,"c"->3)) {println(x + ":" + y)}(2) 常量模式匹配//下面只有"b"被匹配到,輸出2for(("b",y)<-Map("a"->1,"b"->2,"c"->3)) {println(y)}(3) 變量綁定模式匹配//可以綁定變量xxx和yyyfor((xxx@"b",yyy@y)<-Map("a"->1,"b"->2,"c"->3)) {println(xxx + ":" + yyy)}(4) 類型模式匹配//類型value為字符串才能匹配到for((x,y:String)<-Map("a"->1,"b"->"hello","c"->3)) {println(x + ":" + y)}(5) 構(gòu)造方法模式匹配case class Dog(val name:String, val age:Int)case class Cat(val name:String, val age:Int)for (Dog(name,age) <- List(Dog("a",1),Cat("b",2),Dog("c",3))) {println(name + ":" + age)}上面輸出第1個(gè)和第3個(gè)for (List(first,_*) <- List(List(1,2,3), List(4,5,6,7))) {println(first)}(6) 序列模式匹配可以用_*

5) 樣例類和樣例對象

樣列類(case class):使用case修飾的類。就是增加了一些方法,比如unapply。用在上面的模式匹配. 1) 樣例類:是一種特殊的類,可以用于模式匹配。case class是多例,case object是單例。上面已經(jīng)做了一個(gè)例子了,下面再做一個(gè)例子,用到了sealted.trait中前面加入 seatled,表示密封類a) 其修飾的trait,class只能在當(dāng)前文件里面被繼承b) 并且用sealed修飾這樣做的目的是告訴scala編譯器在檢查模式匹配的時(shí)候,讓scala知道這些case的所有情況,scala就能夠在編譯的時(shí)候進(jìn)行檢查,看你寫的代碼是否有沒有漏掉什么沒case到,減少編程的錯(cuò)誤。例:sealed trait Acase class B(id:String,name:String) extends Acase class C(id:String) extends Acase class D(id:String) extends Adef m(x:A) = x match {case B(id,name)=>"1"case C(id)=>"2" // 這一行如果不寫,系統(tǒng)會警告,這樣的好處是提示你不要漏了case D(id)=>"3"} //測試val b = new B("1","zhang3")println(m(b))// 注意,如果注釋掉上面的B,C,D中的任何一句,系統(tǒng)會警告,所以在子類眾多的時(shí)候,要用 sealed修飾帶來的好處。2) 樣例對象(case object)上面看到每個(gè)子類都有自己的屬性,但是實(shí)際開發(fā),可能不需要屬性,如果不定義屬性,編譯器會警告。這時(shí)候需要定義樣例對象(case object)來聲明sealed trait Acase class B(id:String,name:String) extends Acase class C(id:String) extends Acase class D(id:String) extends Acase object E extends Adef m(x:A) = x match {case B(id,name)=>"1"case C(id)=>"2" case D(id)=>"3"case E=>"4"} //測試val b = new B("1","zhang3")println(m(b))println(m(E)) //直接調(diào)用分析:a)case class會先創(chuàng)建對象,而case object可以直接使用b)case class會生成兩個(gè)字節(jié)碼文件,而case object是一個(gè)c)case class生成的伴生對象會自動(dòng)實(shí)現(xiàn) apply和unapply方法,而case object不會使用 case object可以提高速度,減少開銷 例2:spark中的一段代碼如下,看學(xué)生是否看懂?import scala.util.Randomcase class SubmitTask(id: String, name: String)case class HeartBeat(time: Long)case object CheckTimeOutTask //定義樣例對象object Test extends App {var arr = Array(CheckTimeOutTask, HeartBeat(2333), SubmitTask("0001", "task-001"));arr(Random.nextInt(arr.length)) match {case SubmitTask(id, name) => { println(s"$id,$name") }case HeartBeat(time) => { println(time) }case CheckTimeOutTask => { println("check") }}3) Option類型Option類型也是樣本類,表示值是可選的,要么無值,要么有值,Option的子類有Some和None用Some(x) 表示有值,x是真正的返回值用None表示無值val map = Map("cn"->1,"jp"->2) val v = map.get("cn") match { //get方法返回 Option類型case Some(i) => icase None => 0}查看map集合的源代碼: def get(key: A): Option[B]查看some的源代碼:case class Some[+A](x: A) extends Option[A] 查看None的源代碼:case object None extends Option[Nothing] {我們常用 getOrElse("c",0)

9 隱式轉(zhuǎn)換

1)隱式轉(zhuǎn)換簡介

scala提供的一種強(qiáng)大的語法特征,必須掌握。開發(fā)中,會自動(dòng)轉(zhuǎn)換。scala定義了一些隱式轉(zhuǎn)換,會自動(dòng)導(dǎo)入他們。比如 1 to 5 調(diào)用 1.to(5),但是to并不是Int類型的方法,它會自動(dòng)轉(zhuǎn)換為 scala.runtime.RichInt源代碼:系統(tǒng)自動(dòng)導(dǎo)入Predef對象,在scala.Predef中,objectPredef父類LowPriorityImplicits中方法intWrapper(x:Int)=new runtime.RichInt(x)不僅如此, Int還可以轉(zhuǎn)換為其它類型(AnyRef,Integer,Double,Float,Long),可以由其它類型轉(zhuǎn)換而來查看所有的隱式轉(zhuǎn)換scala>:implicit -vscala.Int的伴生對象包含了Int到其它類型的轉(zhuǎn)換implicit def int2long(x:Int) : Long = x.toLongimplicit def int2float(x:Int) : Float = x.toFloatPredef對象中也可以了大量的隱式轉(zhuǎn)換函數(shù),如Scala數(shù)值類型到j(luò)ava數(shù)值類型的轉(zhuǎn)換implicit def byte2Byte(x:Byte) = java.lang.Byte.valueOf(x)正是這些隱式轉(zhuǎn)換函數(shù)的存在,簡化了Scala代碼。

2) 隱式轉(zhuǎn)換

(1)隱式轉(zhuǎn)換函數(shù)Scala默認(rèn)提供了大量的隱式轉(zhuǎn)換,比如Int到Float,但是如果想實(shí)現(xiàn)Float到Int,需要自己定義例:val value : Int = 1.0f // 報(bào)錯(cuò)修改:implicit def m(x:Float) = x.toInt //toInt方法有,但是沒有隱式轉(zhuǎn)換val value : Int = 1.0f原理:當(dāng)編譯機(jī)發(fā)現(xiàn)類型不匹配,就會查找隱私轉(zhuǎn)換函數(shù)--------xjad反編譯----------- public int m(float x){return (int)x;}int value = m(1.0F);System.out.println(value); }注:名稱可以是任意(與參數(shù)類型和返回值有關(guān)),但不要重復(fù),否則隱式轉(zhuǎn)換報(bào)錯(cuò),不過盡量給名字寫的有意義(2) 隱式類隱式類的轉(zhuǎn)換不像隱式轉(zhuǎn)換函數(shù)那么明顯。例;implicit class A (val name:String) { def bark = println(name + " is barking")}//調(diào)用"Nacy".bark //由于String沒有 bark方法,因此會找隱式類,由于A的主構(gòu)造方法是String,就會調(diào)用。---源代碼 public static class Test$A{private final String name;public Test$A(String name) {this.name = name}public void bark(){System.out.println(name + " is barking");}} public final class Test${public void main(String args[]){new Test.A("Nacy").bark();//把“nacy”轉(zhuǎn)換為創(chuàng)建A的對象}}(3) 隱式對象單例對象前加入implicit關(guān)鍵字trait A[T] {def m(x:T):T }//隱式轉(zhuǎn)換對象:整數(shù)的平方implicit object AInt extends A[Int]{def m(x:Int) = x * x}//隱式轉(zhuǎn)換對象:字符串的乘積implicit object BString extends A[String] {def m(x:String) = x * 2}//定了一個(gè)函數(shù):函數(shù)具有泛型參數(shù)def foo[T:A](x:T) = {val obj = implicitly[A[T]] //通過 implicitly方法,知道T的類型,創(chuàng)建A的相應(yīng)子類對象obj.m(x)}//調(diào)用println(foo(5)) //25,從下面源代碼可以看到,翻譯成java時(shí)傳遞兩個(gè)參數(shù)println(foo("5"))//"55"------源代碼----public final class Test${public Object foo(Object x, Test.A o) { //傳遞A的子類對象Test.A obj = (Test.A)(o);return obj.m(x);}public void main(String args[]) {foo(5,傳遞Test.AInt的單例對象);}}public final class Test{interface A{Object m(Object obj);}}public static class AInt implements A{public int m(int x){ return x * x; }}public static class BString implements A{public String m(String x){ return x * 2}}(4) 隱式參數(shù) 上面的implicitly方法換一種形式,定義在參數(shù)中 , 參數(shù)前加了implicit,這種形式的參數(shù)成為隱式參數(shù)上面代碼可以化簡如下:def foo[T:A](x:T)(implicit obj:A[T]) = { //知道T的類型,創(chuàng)建A的相應(yīng)子類對象obj.m(x)}//編譯后的源代碼基本不變(5) 隱式值隱式值也叫隱式變量,前面用implicit修飾例1:implicit val x : Double = 2.55def sqrt(implicit y: Double) = Math.sqrt(y)//測試 scala> sqrt //不指定參數(shù),編譯器再當(dāng)前作用于查找相應(yīng)的隱式值或隱式對象,找到x傳給它--xjad反編譯public final class Test${private final double x = 2.5499999999999998D; public double sqrt(double y) {return Math.sqrt(y);}public void main(String args[]){sqrt(x);}}例2:改寫上面的代碼:trait A[T] {def m(x:T):T }class AInt extends A[Int]{ //普通類def m(x:Int) = x * x}class BString extends A[String] {def m(x:String) = x * 2}implicit val a = new AInt //隱式值,上面的例子是隱式對象implicit val b = new BStringdef foo[T:A](x:T)(implicit obj:A[T]) = { obj.m(x)}//調(diào)用println(foo(5)) //25println(foo("5"))//"55"

3) 隱式參數(shù)使用常見問題

1. 當(dāng)函數(shù)沒有柯里化,implicit關(guān)鍵字組用于函數(shù)列表中的所有參數(shù)scala>def m(implicit x:Double,y:Double) = x * y //所有參數(shù)都作用implicitm: (implicit x: Double, implicit y: Double)Doublescala>implicit val d = 2.5scala>m //結(jié)果 6.252. 隱式函數(shù)使用時(shí)要么全部指定,要么全不指定,不能只指定部分如果上面調(diào)用scala>m(3.0) 就報(bào)錯(cuò)scala>m(3.0,3.0)3. 同類型的隱式值只在當(dāng)前作用域內(nèi)出現(xiàn)1次如果再定義 scala>implicit val d2 = 3.5scala>m // 報(bào)錯(cuò) 4. 在定義隱式函數(shù)時(shí),implicit關(guān)鍵字只能在參數(shù)開頭//報(bào)錯(cuò),不能定義在第2個(gè)參數(shù)def m(x:Double,implicit y:Double) = x * y 5. 如果想達(dá)到函數(shù)def m(x:Double,implicit y:Double)只將參數(shù)y定義為隱式函數(shù)的目的,需要對函數(shù)柯里化//柯里化后,只有參數(shù)y是隱式參數(shù)def m(x:Double)(implicit y:Double) = x * yimplicit val d = 4.0m(3)6. 柯里化的函數(shù)implicit關(guān)鍵字只能作用于最后一個(gè)參數(shù)def m(x:Double)(y:Double)(implicit z:Double) = x * y * z //正確def m(implicit x:Double)(y:Double)(z:Double) = x * y * z //錯(cuò)誤,沒有作用于最后一個(gè) 7. implicit關(guān)鍵字只在隱式參數(shù)中出現(xiàn)1次,對柯里化的函數(shù)也不例外def m(implicit x:Double,implicit y:Double) = x * y // 錯(cuò)誤8. 匿名函數(shù)不能使用隱式參數(shù)val m = (x:Double, y:Double)=>x * y // 正確val m = (implicit x:Double, y:Double)=>x * y9. 柯里化的函數(shù)如果有隱式參數(shù),則不能使用其偏應(yīng)用函數(shù)def m(x:Double)(y:Double) = x * yval t1 = m _ //賦值給t1, 定義兩個(gè)參數(shù)的偏函數(shù)t1(3,0)(4,0)val t2 = m(3.0) _t2(4.0)以上都沒有問題,但是如果下面有隱式參數(shù),則會報(bào)錯(cuò) def m(x:Double)(implicit y:Double) = x * yval p = m _ //報(bào)錯(cuò)

4)隱式轉(zhuǎn)換規(guī)則與問題

(1) 隱式轉(zhuǎn)換的若干規(guī)則a) 作用域規(guī)則必須在當(dāng)前作用域才能起作用。c) 無歧義規(guī)則不能存在兩個(gè)一樣功能的隱式轉(zhuǎn)換函數(shù)。d) 一次轉(zhuǎn)換原則只經(jīng)過1次隱式轉(zhuǎn)換,不能經(jīng)過多次(2) 是否調(diào)用隱式轉(zhuǎn)換非必要的情況下,盡量少用,如果是為了炫耀,大膽使用。

10 類型參數(shù)

1) 簡介

(1) 簡介在類的聲明中,定義一些泛型,然后在類內(nèi)部,就可以使用這些泛型類型。scala泛型和java泛型基本相同,只是Java語法格式為<>,而Scala語法給是為[]//比如: java中List<T> ,而Scala中為 List[T]//比如:trait Map[A,B] extends Iterable[(A,B)] with GenMap[A,B] with scala.collection.Map[A,B] {override def empty:Map[A,B] = Map.empty} (2) 泛型類class Person[T](var name :T)class Student[T,S](name:T, var age:S) extends Person(name)//name前不寫var表示繼承例:新生入學(xué),填寫id時(shí)候,有的人用整數(shù),有的人用字符串class Student[T](val id:T) {def get(hukouId:T) = id + ":" + hukouId}val a = new Student[Int](111)a.get(4)val a = new Student(111) //不寫Int,可以自動(dòng)推斷val a = new Student[String]("111")//測試class Student[A,B](var name:String, var age:Int)println(new Student[String,Int]("a",1).name)(3) 泛型方法與泛型類類似,給某個(gè)函數(shù)在聲明時(shí)指定泛型類型def getCard[T](content: T) = {if (content.isInstanceOf[Int]) 1 //等價(jià)于java的instanceOfelse if (content.isInstanceOf[String]) 2else 3}//測試getCard(111) //1getCard("222") //2getCard(false) //3(4) 類型通配符在java中,采用List<?>來做,但是scala中,沒有采用上面的特性,是通過存在類型來解決類[T,U,..] forSome {type T;type U;...}例://存在類型Array[T] forSome {type T}def printAll(x : Array[T] forSome {type T}) = {for (i <- x) {println(i)}}---源代碼:public void printAll(Object x) {Predef$.MODULE$.genericArrayOps(x).foreach(new Serializable() {public final void apply(Object i) {System.out.println(i);}});}//可以寫簡化形式def printAll(x : Array[_]) = {for (i <- x) {prntln(i)}}

2) 類型變量界定

對泛型范圍進(jìn)行界定,而不是任意類型。比如必須是某個(gè)類的子類,或者是父類,才能正常使用。java中,這么定義://List<? extends Object> 接收object的子類,包括Object//List<? super Integer> 接收Integer的父類,包括Integerscala沒有采用,它采用對應(yīng)<:>:例1:class Person(val name: String) {def makeFriends(other: Person) = println(this.name + "和" + other.name + "交朋友")}class Student(name: String) extends Person(name)class Party[T <: Person](p1: T, p2: T) {def play = p1.makeFriends(p2)}//調(diào)用var p1 = new Student("zhang3")var p2 = new Student("li4")new Party[Student](p1, p2).play例2: def compare[T <:Comparable[T]](first:T,second:T) = {//表示Comparable的子類if (first.compareTo(second)>0) firstelsesecond}調(diào)用;:compare("A,"B”) //B

3) 視圖界定

用<%表示: 相當(dāng)于上面的<:加上隱式轉(zhuǎn)化class Person(val name: String) {def makeFriends(other: Person) = println(this.name + "和" + other.name + "交朋友")}class Teacher(var name: String)class Party[T <% Person](p1: T, p2: T) {def play = p1.makeFriends(p2)}implicit def teacher2Person(t: Teacher) : Person = new Person(t.name)//調(diào)用var p1 = new Teacher("zhang3")var p2 = new Teacher("li4")new Party[Teacher](p1, p2).play

4) 上下文界定

回顧以前:>: 繼承:要求是長輩<: 繼承:要求是低輩<% 繼承+隱式轉(zhuǎn)換 這次T:A T是一個(gè)泛型, A是個(gè)類,要求調(diào)用這個(gè)類的函數(shù)時(shí),必須要隱式引入A[T]。舉個(gè)例子:T是整數(shù)Int,A是Ordering(理解成排序comparator,系統(tǒng)有這個(gè)類),要求使用時(shí)候要引入隱式值Ordering[Int]class Test[T:Ordering](val a:T,val b:T) {def bigger(implicit myComparator:Ordering[T]) {if (myComparator.compare(a,b)>0)println(a +":"+ myComparator.getClass)elseprintln(b)}}new Test(1,2).bigger //2----反編譯----public class Test{private final Object a;private final Object b;public Test(Object a, Object b,){this.a = a;this.b = b; }public void bigger(Ordering myComparator){if (myComparator.compare(a(), b()) > 0)System.out.println(a());elseSystem.out..println(b());}}new Test(1,2).bigger(系統(tǒng)自帶的實(shí)現(xiàn)Int的Ordering對象)

5) 多重界定

(1) T:A:B 隱式引入A[T],B[T](2) T<%A<%B 存在T到A,T到B的隱式轉(zhuǎn)換(3) T1>:T<:T2 T1是T類型的超類,T2也是T類型的超類class A[T]class B[T]implicit val a = new A[String]implicit val b = new B[String]//1.當(dāng)前作用域中,必須存在兩個(gè)隱式值,類型為 A[T],B[T]def test[T:A:B](x:T) = println(x) test("測試1")implicit def t2A[T](x:T) = new A[T]implicit def t2B[T](x:T) = new B[T]//2.當(dāng)前作用域中,必須存在T到A,T到B的隱式轉(zhuǎn)換def test2[T <% A[T] <% B[T]](x:T) = println(x)test2("測試2")

6) 協(xié)變與逆變

//解決問題,如果Child是Father的子類,那么List<Child>是不是List<Father>的子類,答案:不是,但這會造成很多問題。但Scala只要靈活運(yùn)用協(xié)變與逆變,就可以解決這個(gè)問題協(xié)變 +T 當(dāng)A是B的子類, 那么func(A) 是func(B)的子類例:class Fatherclass Child extends Fatherclass Test[+T]var x = new Test[Father]var y = new Test[Child]//此事,x也是y的父親x = y //正確y = x //錯(cuò)誤逆變 -T當(dāng)A是B的子類, 那么func(A) 是func(B)的父類

===========================================================================
11 scala并發(fā)編程基礎(chǔ)(講義已經(jīng)單獨(dú)做成doc文檔:講義-Actor編程.docx)
1) 簡介
(1) 并發(fā)和并行
并發(fā):在一臺處理器上“同時(shí)”處理多個(gè)任務(wù),一個(gè)時(shí)刻只有一個(gè)任務(wù)跑
并行:在多臺處理器上同時(shí)處理多個(gè)任務(wù),一個(gè)時(shí)刻有有個(gè)任務(wù)跑。

優(yōu)化:并發(fā):增加進(jìn)程或者線程,縱向擴(kuò)展并行:增加cpu,橫向擴(kuò)展Actor模型:可以同時(shí)解決縱向和橫向擴(kuò)展

總結(jié)

以上是生活随笔為你收集整理的Scala编程指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

中字幕视频在线永久在线观看免费 | 狠狠狠综合 | 可以免费观看的av片 | 午夜三级影院 | 在线观看免费版高清版 | 国产成人精品综合 | 91精品视频播放 | 欧美国产日韩激情 | 激情视频在线观看网址 | 欧美一级片在线 | 国产视频亚洲视频 | 国产精品九九九九九九 | 在线观看av中文字幕 | 丁香花在线观看视频在线 | 久久婷婷色综合 | 中文字幕一区二区在线播放 | 成年人在线观看 | 国产一区免费观看 | 久草视频99| 91久久人澡人人添人人爽欧美 | 97在线看 | av福利在线免费观看 | 夜添久久精品亚洲国产精品 | 国产人在线成免费视频 | av亚洲产国偷v产偷v自拍小说 | 日本中文字幕在线看 | 午夜美女wwww | 国产视频精品网 | 免费看黄视频 | 免费视频二区 | 中文字幕视频三区 | 精品免费久久久久 | 亚洲狠狠干| 激情综合网五月婷婷 | 在线观看国产麻豆 | 国产精品久久久av | 丁香花中文字幕 | 久久夜色网| 成在人线av | 精品国产伦一区二区三区观看方式 | 99在线热播精品免费99热 | 一区二区三区视频网站 | 午夜在线看 | 国产美女永久免费 | 国产精品毛片一区视频播 | 免费福利视频网 | 永久精品视频 | 午夜在线观看 | 日韩二区三区在线观看 | 一区二区三区免费在线观看 | 在线观看亚洲国产 | 中文乱码视频在线观看 | 激情五月av | 日日弄天天弄美女bbbb | 中文字幕一区三区 | 国产精品第十页 | 欧美亚洲一区二区在线 | 在线一区观看 | 狠狠狠色丁香婷婷综合久久88 | 91亚洲视频在线观看 | 久草视频免费观 | 久久艹人人 | 免费在线观看不卡av | 国产精品普通话 | 91精品久久久久久综合乱菊 | 精品国产自在精品国产精野外直播 | 日韩在线观看中文字幕 | av网站手机在线观看 | 亚洲国产精品影院 | 久草网在线视频 | 色偷偷88888欧美精品久久 | 国产精品亚洲片在线播放 | 成人三级黄色 | 亚洲国产中文在线观看 | 久草国产在线 | 亚洲精品午夜视频 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 国产亚洲精品电影 | 亚洲综合色av | 久久高清国产 | 天天干天天干天天色 | 日韩.com| 97在线免费观看视频 | 亚洲一区久久 | 日韩网站一区二区 | 人人看人人艹 | 久久久久久久久久久久国产精品 | 91av视频在线观看免费 | 麻豆国产电影 | 精品久久91| 国内外成人在线 | 伊香蕉大综综综合久久啪 | 日韩av中文在线 | a级片在线播放 | bayu135国产精品视频 | 成人av电影在线播放 | 色综合天天狠天天透天天伊人 | 综合色综合色 | 欧美性极品xxxx娇小 | 不卡的av电影在线观看 | 99在线精品视频观看 | 国产精品久久影院 | 国产一级a毛片视频爆浆 | 99视频一区二区 | 精品一二三区视频 | 精品欧美日韩 | 欧美福利精品 | 三级黄色免费 | 久久官网| 西西人体4444www高清视频 | 成人免费毛片aaaaaa片 | 最近中文字幕mv免费高清在线 | 亚洲伦理一区二区 | 亚洲成人资源网 | 久久成人资源 | 国产精品一区二 | 女人久久久久 | 91社区国产高清 | 久久免费高清视频 | 国产不卡片 | 日本久久中文字幕 | 久久福利影视 | 日韩在线视频精品 | 亚洲女同videos | 国产在线高清精品 | 黄色成人av在线 | 黄p网站在线观看 | 999久久久精品视频 日韩高清www | 99国产精品一区二区 | 少妇精品久久久一区二区免费 | 在线日韩av| 91精品国产欧美一区二区成人 | av在线免费网| 国产精品麻豆果冻传媒在线播放 | 91精品国自产在线 | 在线观看视频在线 | 久久社区视频 | 国产精品a久久 | 国产精品影音先锋 | 久久精品中文视频 | 91网站在线视频 | 日本精品视频在线观看 | 九九九九精品九九九九 | 精品国产美女在线 | 日日躁夜夜躁aaaaxxxx | 香蕉影院在线观看 | 色吧av色av | 91一区二区三区久久久久国产乱 | 91精品啪在线观看国产 | 91九色在线视频观看 | 91国内在线 | 美女网色 | 麻豆一区在线观看 | 欧美久久久久 | 国产精品国产三级国产不产一地 | 免费在线观看成人av | a黄色片在线观看 | 国产尤物一区二区三区 | 色香蕉在线 | 国产91在线看| 国产精品成久久久久 | 高清av中文字幕 | 搡bbbb搡bbb视频 | 日韩在线视频免费看 | 亚洲成人资源在线 | 日韩欧美在线不卡 | 亚洲3级 | 精品国产日本 | 黄色亚洲片 | 黄色免费在线看 | 亚洲精品视频观看 | 免费一级特黄毛大片 | 最近中文字幕mv免费高清在线 | 天天操天天摸天天干 | 日韩天堂网| 久久免费在线视频 | 韩国av电影在线观看 | 最近日本mv字幕免费观看 | 国产精品久久久亚洲 | 欧美99精品 | 国产精品成人aaaaa网站 | 九九九免费视频 | 日韩va在线观看 | 中文字幕有码在线播放 | 成人性生交视频 | 国产精品色视频 | 999男人的天堂 | 国产另类av | 久久亚洲成人网 | 99精品视频在线观看播放 | 欧美日韩精品免费观看视频 | 国产精品美女www爽爽爽视频 | 中文字幕在线日本 | 国产性天天综合网 | 五月激情姐姐 | 国产精品久久久久久久毛片 | 天天爽人人爽 | 国产呻吟在线 | 亚洲成人麻豆 | a黄色一级 | 正在播放亚洲精品 | 精品一区二区在线观看 | 日韩欧美一区二区在线观看 | 深夜免费福利视频 | 国产在线不卡精品 | 精品一区二区免费在线观看 | 午夜精品一区二区三区可下载 | 日韩在线精品一区 | 久草在线免费资源 | 国产精品 国产精品 | 在线视频手机国产 | 中文在线中文a | 成人超碰97 | 精品国产精品国产偷麻豆 | 国产一二区视频 | 国产亚洲人 | 国产精品美女免费视频 | 久久综合久久88 | 亚洲三区在线 | 最近中文字幕大全中文字幕免费 | 亚洲美女精品区人人人人 | 在线性视频日韩欧美 | 91av在线免费观看 | 国产精品成人一区二区三区吃奶 | 国产欧美在线一区二区三区 | 玖玖玖国产精品 | 日韩超碰 | 18做爰免费视频网站 | 国产精品对白一区二区三区 | 日韩精品视频第一页 | 99热播精品 | 一区二区三区在线免费播放 | 日日夜夜干 | 狠狠色丁香 | av在线免费观看黄 | 国产色综合| www蜜桃视频 | 91免费高清在线观看 | 免费热情视频 | 日韩免费观看一区二区 | 久久免费视频在线观看 | 国产成人黄色网址 | 在线视频 国产 日韩 | av解说在线观看 | 日韩高清精品免费观看 | 色婷婷激情四射 | av中文字幕电影 | 亚洲精品白浆高清久久久久久 | 在线播放 亚洲 | 天天爽夜夜操 | 成人免费观看网址 | 久久看视频 | 亚洲黄色网络 | 国产精品手机播放 | 成人av免费在线看 | 亚洲午夜久久久影院 | 午夜av不卡 | 黄色三级网站 | 毛片的网址 | 久久亚洲福利视频 | 一区在线免费观看 | 天天干,天天操 | 天天色天天 | 久久久久亚洲精品男人的天堂 | 亚洲精品久久久久久久蜜桃 | 玖玖爱在线观看 | 精品综合久久 | 欧美日韩亚洲在线观看 | 亚洲精品国产精品国 | 成人激情开心网 | 狠狠的操你 | 国产中文字幕91 | 超级碰碰视频 | 狠狠做深爱婷婷综合一区 | 在线观看播放av | 99精品区 | 国产黄色美女 | 西西www4444大胆视频 | 一本一本久久a久久 | 蜜臀av夜夜澡人人爽人人桃色 | 国产色网站 | 亚洲午夜精品在线观看 | 久久手机精品视频 | 国产精品大全 | 国内三级在线观看 | 69国产精品成人在线播放 | 国产精品久久久久aaaa | 五月婷婷影院 | 97色噜噜 | 一区二区精品国产 | 四虎在线视频免费观看 | 日韩欧美亚州 | 精品国产一区二区在线 | 久久国精品 | 亚洲精品xxxx | 久久伊人婷婷 | 91精品少妇偷拍99 | 天天操天天操天天操天天操 | 欧美亚洲久久 | 男女激情免费网站 | 91cn国产在线| 亚洲夜夜综合 | 久久精品久久精品久久39 | 中文字幕av最新更新 | 91成人免费 | 色综合网 | 中文字幕av免费 | 久久69av| 五月香婷 | 中文字幕av在线 | 成人av免费 | 私人av | 在线观看免费日韩 | 手机av在线网站 | 亚洲一级久久 | 国产精品久久精品 | 国产一级黄色av | 91成人免费在线视频 | 久久久精品网站 | 精品在线小视频 | av在线收看| 中文字幕五区 | www久草 | 亚洲视频在线免费观看 | 日本精品久久久久中文字幕 | 狠狠操影视 | 日韩视频在线播放 | 91在线一区 | 高清免费av在线 | 日本中文字幕系列 | 日本久久成人中文字幕电影 | 在线a视频免费观看 | 91在线免费播放视频 | 毛片的网址 | 精品欧美一区二区精品久久 | 91高清在线 | 欧美二区三区91 | 69av国产 | 国产中文字幕大全 | 啪啪免费视频网站 | 天天操天天色天天射 | 最近2019中文免费高清视频观看www99 | 亚洲爱av | 中文国产成人精品久久一 | 日韩在线短视频 | 97视频入口免费观看 | 欧美日韩国产色综合一二三四 | 成人免费观看大片 | 99精品视频一区 | 成人aaa毛片 | 国产精品18久久久久久久 | 日韩啪啪小视频 | 色激情五月 | 国产精品一区二区在线观看免费 | 91精品在线播放 | 国产一级黄色电影 | 亚洲视屏一区 | 日韩免费在线观看视频 | 亚洲国产精品成人精品 | 精精国产xxxx视频在线播放 | 99精品免费在线观看 | 在线观av| 欧美激情片在线观看 | 在线97 | 日韩免费高清在线 | 97超在线| 久久国产精品免费看 | 亚洲精品av中文字幕在线在线 | 成人a级大片 | 日日干夜夜骑 | 91av在线视频免费观看 | 成年人黄色免费看 | 99精品国产亚洲 | 欧美日韩在线免费观看视频 | 国产色网站| 黄色av一级片 | 一区精品在线 | 色黄视频免费观看 | 毛片网在线播放 | 久草在线高清视频 | 久久不色 | 久久精品成人热国产成 | 亚洲欧洲一级 | 狠狠操.com | 国产高清无线码2021 | 欧美aaaxxxx做受视频 | 中文字幕一区二区在线观看 | 国产小视频在线 | 99视频国产精品免费观看 | 六月婷色| 亚洲人在线7777777精品 | 99久久精品免费 | 亚洲人成免费网站 | 国产资源在线视频 | 亚州激情视频 | 天天激情天天干 | 日韩在线短视频 | 久久久久国产精品一区二区 | 色九色| 久久精品久久久久 | 在线 视频 亚洲 | 久艹视频在线免费观看 | 久久精品国产99国产 | av黄网站 | 国产成人精品亚洲 | 免费久久网 | 欧美日韩aaaa| 美女免费视频网站 | av色图天堂网 | 精品免费观看 | 久久久久久久久久网 | 国产黄色免费电影 | 久久9999久久免费精品国产 | 麻豆免费在线视频 | 在线a人片免费观看视频 | 91视频中文字幕 | 国产91aaa| 国产亚洲精品成人av久久ww | 国产在线日本 | 久久高清国产 | 婷婷福利影院 | 日韩成人在线一区二区 | 99爱精品视频 | 日韩精品一区电影 | 亚洲欧美成人网 | 亚洲综合在线视频 | 亚洲人成人在线 | 国产 欧美 在线 | 夜夜爽www | 天天插日日射 | 一级黄色片在线免费观看 | 久草影视在线观看 | av成人在线电影 | 国产在线中文字幕 | 久草久热 | 国产裸体无遮挡 | 日韩av成人免费看 | 中文字幕国产精品一区二区 | 欧美成人在线网站 | 欧美激情综合五月色丁香 | 天天操天天摸天天爽 | 久久视频免费在线观看 | 国产成人精品久久亚洲高清不卡 | 成人一区二区三区中文字幕 | 国产麻豆精品在线观看 | 天天天在线综合网 | 91网页版免费观看 | 成人三级网站在线观看 | 国产原创在线视频 | 日本精品视频在线观看 | 中文字幕免费一区二区 | 久草在线免费播放 | 亚洲资源在线网 | 96亚洲精品久久久蜜桃 | 在线国产视频一区 | 久久草视频 | 久久手机免费观看 | 欧美夫妻生活视频 | 五月婷婷影视 | 韩国在线视频一区 | 日日操操操 | 国产亚洲在线 | 精品二区久久 | 日韩中文字幕免费在线观看 | 国产免费一区二区三区网站免费 | 国产精品久久一 | 中文字幕在线影院 | 丁香电影小说免费视频观看 | 久久高清 | 国产精品亚洲视频 | 成人免费视频观看 | 天天人人综合 | 欧美日韩精品在线视频 | 在线播放日韩av | 久久少妇免费视频 | 国产黄色电影 | 国产精品久久久久免费 | 91视频 - v11av | 91视频88av| 日韩激情在线 | 精品国产乱码久久久久久久 | 中文字幕在线资源 | 久久久精品福利视频 | 国产成本人视频在线观看 | www成人精品 | 国产午夜精品福利视频 | 福利av在线 | av电影 一区二区 | 亚洲免费成人av电影 | 久久婷综合 | 国产亚洲精品久久久久久久久久久久 | av在线日韩| 免费网站黄 | 日韩精品在线播放 | 国产精品一区二区三区在线看 | 国产黄网在线 | 99久久99热这里只有精品 | 在线观看午夜av | 亚洲一区二区三区毛片 | 看污网站| 三级视频日韩 | 综合婷婷丁香 | 日韩二区三区在线 | 国产黄在线播放 | 国产黄色精品在线观看 | 国产在线观看99 | 97人人模人人爽人人少妇 | 黄色一及电影 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 欧美一区在线观看视频 | 欧美极品xxx | 一级α片免费看 | 亚洲午夜精品久久久久久久久 | 久久综合久久综合久久综合 | 91免费国产在线观看 | 伊人婷婷综合 | 激情五月综合 | 在线观看国产高清视频 | 日本精品在线视频 | 夜色资源站国产www在线视频 | 精品视频在线看 | 午夜精品福利一区二区 | 成人禁用看黄a在线 | 日韩av一区二区在线影视 | 欧美一区二区三区免费观看 | 伊人亚洲综合网 | 国产成人久久 | 免费av在线网站 | 欧美日韩一区二区三区不卡 | 麻豆超碰 | 色噜噜在线观看 | 欧美aaa大片 | 一本一本久久a久久精品综合小说 | 国产精品你懂的在线观看 | 日韩 在线 | 国产一区福利 | 国产淫片 | 亚洲精品午夜久久久久久久久久久 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 激情五月婷婷综合网 | 国产一区二区影院 | 日日操操操 | 亚洲理论电影网 | 五月综合婷 | 99视频国产精品 | 国产精品女人网站 | a特级毛片| 国产午夜在线观看视频 | 久久久免费国产 | 日韩av在线看 | 久久久久久久久久电影 | 亚洲国产大片 | 精品91久久久久 | 日本精品视频一区二区 | 成人免费在线观看av | 免费在线视频一区二区 | 99视频偷窥在线精品国自产拍 | 色91在线 | 国产精品va在线观看入 | 又黄又刺激视频 | 国产成人一区二区啪在线观看 | 日韩激情综合 | 欧美 日韩精品 | 正在播放一区 | 中文在线免费一区三区 | 天天操天天色天天 | 亚洲成年人在线播放 | 激情五月激情综合网 | 色综合久久综合中文综合网 | 在线观看视频国产一区 | 欧美日韩国产在线精品 | 在线婷婷| 国产一区在线免费观看 | 夜夜躁天天躁很躁波 | 久久国产精品久久精品国产演员表 | 99久久久久国产精品免费 | 亚洲欧美国产视频 | 成人亚洲免费 | 国产成人一区二区三区 | 激情久久久久久久久久久久久久久久 | 三级午夜片 | 日日爱av | 免费视频91蜜桃 | 69视频在线 | 亚洲专区欧美专区 | 美女一级毛片视频 | 久久呀| 最近免费中文字幕 | 久草免费在线观看视频 | 色婷婷色| 在线免费精品视频 | 香蕉视频91 | a色视频 | 久久久久久久国产精品影院 | 欧美日韩国产一区二区三区 | 操一草 | 亚洲国产网址 | 日韩毛片在线免费观看 | 国产资源精品在线观看 | 91九色成人 | 亚洲综合色站 | 天天摸天天干天天操天天射 | 国产丝袜制服在线 | 综合色站 | 久久精品国产久精国产 | 天天操综合网站 | 激情视频91 | 69av在线视频 | 最新av中文字幕 | 亚洲国产中文字幕在线 | 久久久精品国产免费观看同学 | 国产精品av一区二区 | 国产精品一区久久久久 | 亚洲天堂网在线观看视频 | www.色五月 | 91精品啪在线观看国产 | 三级av片 | 久久草在线视频国产 | av在线网站免费观看 | 日韩动态视频 | 国产免费精彩视频 | 超碰日韩| 欧美综合国产 | 激情av五月婷婷 | 国产69久久久 | 亚洲 欧美变态 另类 综合 | www成人av| 欧美激情视频一区二区三区 | 日韩专区在线观看 | 久久久久久美女 | 久久国产成人午夜av影院宅 | 久久精品久久精品久久 | 欧美日韩在线精品一区二区 | 69人人| 91传媒在线观看 | 久久久国产一区二区三区四区小说 | 欧美一进一出抽搐大尺度视频 | 国产a精品 | 亚洲国产精彩中文乱码av | 国产精品va在线播放 | 国产999精品久久久久久麻豆 | 久久99久久精品 | 亚洲精品黄色 | 欧美尹人| 久久久色 | 亚洲作爱 | 一区二区中文字幕在线观看 | 欧美91精品国产自产 | 国产高清小视频 | 国产精品毛片一区二区在线看 | 99色资源| 久久99国产精品免费网站 | 亚洲精品在线资源 | 国产精品18久久久久久不卡孕妇 | 日本黄色a级大片 | 欧美最爽乱淫视频播放 | av国产网站 | 香蕉97视频观看在线观看 | 久久精品免视看 | 日本久久综合视频 | 久久久久久久久免费视频 | www.夜夜骑.com | 一本一本久久a久久精品综合 | 天天干天天碰 | 久久免费黄色网址 | 精品亚洲欧美一区 | 国产午夜精品免费一区二区三区视频 | 国产精品18久久久久久vr | 午夜 在线| 五月丁婷婷| 亚洲欧美一区二区三区孕妇写真 | 99精品在线观看 | 精品国产伦一区二区三区免费 | 亚洲自拍偷拍色图 | 精品一区二区三区四区在线 | 欧洲一区精品 | 97色在线观看 | 国产精品欧美久久久久无广告 | 日韩av在线看 | 国产最新视频在线观看 | 日韩专区中文字幕 | 亚洲国产精品日韩 | 美女视频黄是免费的 | 日韩免费观看高清 | 日韩特黄一级欧美毛片特黄 | 亚洲精欧美一区二区精品 | 婷婷色网 | 国产主播99 | 国产成人a亚洲精品 | 99在线高清视频在线播放 | 99视频99| 韩日电影在线免费看 | 韩国精品视频在线观看 | 欧美 日韩 成人 | 国产欧美综合在线观看 | 啪啪免费视频网站 | 亚洲精品久久久久www | 日韩精品一区二区三区不卡 | 日本精品一区二区 | 91久久久久久久一区二区 | 久久免费av | 国产精品色婷婷 | 97超碰人人在线 | 三级av在线播放 | 国产一区在线播放 | 日韩av播放在线 | 99久视频 | 91c网站色版视频 | 操综合| 在线观看视频免费大全 | 99精品乱码国产在线观看 | 97超碰人人澡 | 日韩精品中文字幕一区二区 | 中文资源在线官网 | 中文一区在线观看 | 国产免费国产 | 在线视频观看亚洲 | 欧美日韩一区二区视频在线观看 | 一区二区精品视频 | 月下香电影 | www在线观看视频 | 天天插综合 | 久久综合视频网 | 91精品国产高清自在线观看 | 日韩欧美极品 | 久久精品一区二区三区国产主播 | 黄色免费在线看 | h视频日本 | 99热精品视 | 四虎免费在线观看视频 | 成人理论电影 | 日韩免费在线视频观看 | 日韩在线视频国产 | 亚洲成人影音 | 日韩伦理片一区二区三区 | 99c视频高清免费观看 | www.91国产| 综合国产视频 | 天天草天天爽 | 天海冀一区二区三区 | 女人高潮特级毛片 | 日韩欧美精品在线视频 | 麻豆视频在线播放 | 99国产精品久久久久久久久久 | 97色视频在线| 欧美一区二区三区不卡 | 国产精品久久免费看 | 怡红院av久久久久久久 | 国产一级不卡视频 | 在线视频专区 | 最新免费av在线 | 成人久久久久久久久 | 超碰99人人| 国产精品成人免费一区久久羞羞 | 国产五月天婷婷 | 日韩精品91偷拍在线观看 | 日韩色高清 | 黄色免费网站下载 | 久久综合久久久 | 丁香婷婷久久 | 免费精品在线 | 91视频91自拍 | 又黄又刺激又爽的视频 | 99久久激情| 国产国产人免费人成免费视频 | 欧美成人精品欧美一级乱 | 亚洲国产av精品毛片鲁大师 | 精品国产一区二区三区久久久久久 | 91视频免费网站 | 欧美成人性网 | 美女视频是黄的免费观看 | 国产精品国产三级国产aⅴ无密码 | 在线成人国产 | 亚洲天天 | 亚洲欧美日韩国产精品一区午夜 | 国产精品国产三级国产aⅴ入口 | 女人18毛片a级毛片一区二区 | 狠狠干夜夜爱 | 国产自产高清不卡 | 久久精品欧美一区 | 久久极品 | 国内免费久久久久久久久久久 | 99精品国产高清在线观看 | 五月天久久精品 | 久久综合国产伦精品免费 | 香蕉精品在线观看 | 福利视频 | 狠狠色丁香久久婷婷综合_中 | 国产中文伊人 | 丝袜美女在线观看 | 久久久久久久久久久高潮一区二区 | 国内精品久久久久久久久久清纯 | 99久久精品国产欧美主题曲 | 九九热视频在线免费观看 | 成年人在线免费看视频 | 中文字幕在线电影 | 成人av在线影视 | 亚洲性xxxx| 亚州精品天堂中文字幕 | 91九色网址 | 日韩手机视频 | 色综合久久久久久中文网 | av黄色免费网站 | 亚洲影视九九影院在线观看 | 国产精品综合久久久久 | 国际精品久久久久 | 91视频com | 在线蜜桃视频 | 久久综合影音 | 福利视频一区二区 | av高清影院 | 成人avav| 国产欧美在线一区 | 久久久天天操 | 精品国产乱码久久久久久三级人 | 中文字幕资源在线观看 | 日韩一区二区三区不卡 | 免费看av片网站 | 亚洲国产精品传媒在线观看 | 视频福利在线观看 | 久久视频6 | 99精品偷拍视频一区二区三区 | 国产精品激情偷乱一区二区∴ | 久久久亚洲成人 | 久久香蕉一区 | 久久久久亚洲精品男人的天堂 | 亚洲毛片视频 | 中文字幕在线乱 | 国产精品人人做人人爽人人添 | 亚洲综合成人婷婷小说 | 91福利视频一区 | 免费在线91 | 国产在线视频在线观看 | 免费黄在线观看 | 欧美日韩不卡在线视频 | 日韩免费观看视频 | 亚洲精品成人av在线 | 国产精品麻豆视频 | 永久精品视频 | 五月婷婷婷婷婷 | 美女国产免费 | 久久久久久激情 | 午夜精品一区二区三区视频免费看 | 色综合网在线 | 亚洲欧美成人综合 | 国产永久免费 | 亚洲综合成人婷婷小说 | 国产小视频在线 | 97精品国产aⅴ | 国产高清日韩 | 欧洲成人av | 国产精品久久久视频 | 在线观看小视频 | 在线成人一区二区 | 亚洲做受高潮欧美裸体 | 亚洲一区免费在线 | 亚洲欧洲成人精品av97 | 国产尤物一区二区三区 | 国产午夜激情视频 | 美国人与动物xxxx | 亚洲精品国产精品国自 | 麻豆传媒视频在线播放 | 久久av影视 | 午夜国产福利在线观看 | 97超碰成人在线 | 亚洲黄色一级大片 | 亚洲精品视频免费看 | 国产字幕在线播放 | 国际精品久久 | 成人亚洲精品国产www | 又长又大又黑又粗欧美 | 夜夜天天干 | 西西www4444大胆在线 | 香蕉视频久久久 | 国产成人a v电影 | 色五月激情五月 | 日韩首页| 久久免费看av | 在线黄色毛片 | 91av视频在线免费观看 | 国产精品嫩草影院99网站 | 九色福利视频 | 久久久久久久久久网 | 一区二区三区四区精品 | 国产无套精品久久久久久 | 四虎小视频 | 天天干天天干天天射 | 日韩成人不卡 | 99免费精品 | 日韩视频在线不卡 | 国产一二三区av | 99re视频在线观看 | 四虎永久视频 | 日韩在线看片 | av中文字幕网 | 国产福利一区二区在线 | 操操操av| 最近中文字幕免费av | 国产成人中文字幕 | 亚洲伊人网在线观看 | 波多野结衣视频在线 | 国产明星视频三级a三级点| 国产99久久九九精品免费 | 日韩av线观看 | 色婷婷综合久久久 | 超碰在线人人97 | 国产精品久久久久久久久久久久午夜 | 亚洲国产中文字幕 | 久久成人国产精品 | www.69xx| 美女视频免费一区二区 | 成人免费看片网址 | 天天天天天天操 | 91九色精品 | 久久香蕉电影网 | 中文字幕在线看视频国产 | 81国产精品久久久久久久久久 | 玖玖视频网 | 亚洲精品午夜视频 | 热久久免费视频精品 | 亚洲三级国产 | 日韩在线视频观看免费 | 国产a级片免费观看 | 日日干激情五月 | av在线电影播放 | 成人在线视频观看 | 日韩女同av | 婷婷色站 | 中文资源在线播放 | 国内偷拍精品视频 | 精品国产免费看 | 国产一二三在线视频 | 日韩高清精品免费观看 | 久久免费公开视频 | 最近高清中文在线字幕在线观看 | 五月婷婷中文 | 亚洲精品66 | 久久精品国产99国产 | 尤物97国产精品久久精品国产 | 在线视频观看国产 | 久久人网 | 国产一线二线三线在线观看 | av女优中文字幕在线观看 | 日韩在线免费小视频 | 午夜视频在线观看一区二区三区 | 日韩av资源站 | 亚洲男男gaygay无套 | av色图天堂网 | 激情婷婷六月 | 2024av| 欧美粗又大 | 337p日本欧洲亚洲大胆裸体艺术 | 亚洲区色 | 黄色大片入口 | 久久免费视频一区 | 黄色成人小视频 | 日日成人网 | 808电影免费观看三年 | 最近高清中文在线字幕在线观看 | 五月婷婷久久综合 | 久草在线一免费新视频 | 蜜桃av综合网 | 在线观看国产亚洲 | 五月天天色 | 欧美精品一区二区在线播放 | 久久9999久久免费精品国产 | 中文字幕在线影院 | 国产一级一级国产 | 最近日本字幕mv免费观看在线 | 91在线视频免费播放 | 免费精品在线视频 | 狠狠狠综合 | 久久99热精品 | 超碰在线天天 | 欧洲一区精品 | 国产精品2019 | 亚洲影音先锋 | 在线观看麻豆av | 狠狠躁天天躁 | 欧美analxxxx| 国产精品99久久久久久久久 | 国产黄色片免费看 | 精品一区91 | 国产在线精品观看 | 免费色视频网站 | 成人天堂网 | 午夜电影中文字幕 | 国产不卡在线观看视频 | 中文字幕一区二区三区四区视频 | av免费黄色 | 天天综合久久 | 五月天激情视频 | 97人人网 | 2019中文字幕第一页 | 日韩成人免费在线观看 | 国产一区二区高清不卡 | 手机在线永久免费观看av片 | 色视频成人在线观看免 |