成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Scala講座:函數(shù)式語(yǔ)言的體驗(yàn)

開發(fā) 后端
本文選自Scala講座的第五篇的內(nèi)容,介紹了Scala的函數(shù)定義,引入單例對(duì)象內(nèi)的方法,匿名函數(shù)的定義,在表達(dá)式中作為占位符的下劃線,部分函數(shù)的定義,Scala中方法和函數(shù)的關(guān)系,高階函數(shù)和延遲評(píng)估參數(shù),模式匹配,Case類,將模式匹配與for語(yǔ)句組合,希望大家喜歡。

本文節(jié)選自最近在日本十分流行的Scala講座系列的第五篇,由JavaEye的fineqtbull翻譯。本系列的作者牛尾剛在日本寫過(guò)不少有關(guān)Java和Ruby的書籍,相當(dāng)受歡迎。

序言

這一次講的不是作為Java改良版的Scala語(yǔ)言中所具有強(qiáng)大的純面向?qū)ο蠊δ埽且院瘮?shù)式語(yǔ)言來(lái)介紹他。函數(shù)本身是對(duì)象,他可以被賦值給變量,或者作為方法的參數(shù)來(lái)傳遞,我們把他作為“第一類對(duì)象”來(lái)看一下他的處理方法。另外也讓讀者體驗(yàn)一下函數(shù)式語(yǔ)言特有的模式匹配的強(qiáng)大功能。好,讓我們馬上出發(fā),開始我們第三次迷你旅行吧。

Scala的函數(shù)定義

在Scala中方法被作為函數(shù)用def語(yǔ)句以“def 函數(shù)名(參數(shù)類表): 返回值 = 函數(shù)體”格式來(lái)定義。

  1. def foo(s: String, n: Int): Int = {  
  2. s.length * n  
  3. }  

但是函數(shù)體僅由單個(gè)句子來(lái)構(gòu)成的話可以省略{}。

  1. def foo(s: String, n: Int): Int = s.length * n 

還有,類型推斷對(duì)于返回值也是有效的,在允許的情況下是可以省略他的類型的(函數(shù)定義中,參數(shù)的類型則不可省略)。但是為了理解方便,除了交互式環(huán)境下以腳本語(yǔ)言方式使用外,還是作為標(biāo)記保留下來(lái)比較好吧。

  1. scala> def foo(s: String, n: Int) = s.length * n  
  2. foo: (String,Int)Int  
  3. scala> foo("Zhang Fei"3)  
  4. res0: Int = 27 

為了聲明無(wú)返回值的函數(shù)可以將返回值定義為Unit。這個(gè)與Java中的void相同。

  1. def bar(s: String, n: Int): Unit = for(i <- 1 to n) print(s) 

上述函數(shù)的目的是為了執(zhí)行被認(rèn)為是副作用的打印n次傳入字符串,所以返回值是Unit。附帶說(shuō)一下,Unit唯一的實(shí)例是用()文本來(lái)表示。

引入單例對(duì)象內(nèi)的方法

這些方法一般都定義在類之中,但是如果想單獨(dú)使用它的話,通常將其定義在單例對(duì)象中。

  1. object MyFunctions {  
  2. def foo(s: String, n: Int): Int = s.length * n  
  3. def bar(s: String, n: Int): Unit = for(i <- 1 to n) print(s)  
  4. }  

為了使用foo或bar這些方法,通常指定單例對(duì)象名和方法名來(lái)調(diào)用他。

  1. scala> MyFunctions.foo("Zhang Fei"3)  
  2. res1: Int = 27 
  3. scala> MyFunctions.bar("Zhang Fei"3)  
  4. Zhang FeiZhang FeiZhang Fei  

如下所示將方法引入之后就不用一次一次的指定單例對(duì)象名了。下面引入了所有MyFunctions里的方法。

  1. scala> import MyFunctions._  
  2. import MyFunctions._  
  3. scala> foo("Zhang Fei"3)  
  4. res0: Int = 27 
  5. scala> bar("Zhang Fei"3)  
  6. Zhang FeiZhang FeiZhang Fei  

匿名函數(shù)的定義

到此為止,每一次的函數(shù)定義中都指定了函數(shù)名,但是如果能不指定函數(shù)名就更方便了。因?yàn)榧词箾](méi)有函數(shù)名,只要將函數(shù)體作為參數(shù)來(lái)傳遞或賦值給變量之后,該函數(shù)實(shí)例也就能確定了。這類函數(shù)稱為匿名函數(shù)(anonymous function),以“參數(shù)表 => 函數(shù)體”格式來(lái)定義。例如可以用如下形式來(lái)定義取得字符串長(zhǎng)度的函數(shù)。

  1. scala> (s:String) => s.length 

如果僅這樣定義的話,該語(yǔ)句結(jié)束后該函數(shù)就消失了,為了能夠持續(xù)使用該函數(shù)就需要,或者持續(xù)定義該函數(shù)并適用他,或者將他賦值給變量,或者將他作為參數(shù)傳給別的函數(shù)。

  1. scala> ((s:String) => s.length)( "Zhang Fei"//對(duì)字符串直接適用函數(shù)文本  
  2. res2: Int = 9 
  3.  
  4. scala> val ssize = (s:String) => s.length //將函數(shù)賦值給變量  
  5. ssize: (String) => Int =   
  6. scala> ssize("Zhang Fei"//用變量來(lái)調(diào)用函數(shù)  
  7. res3: Int = 9 
  8. scala> List("Zhang ""Fei").map((s:String) => s.length) //對(duì)于列表每一項(xiàng)目都適用同一函數(shù)文本  
  9. res4: List[Int] = List(63)  
  10. scala> List("Zhang ""Fei").map(ssize) //對(duì)于列表每一項(xiàng)目都適用同一函數(shù)變量  
  11. res5: List[Int] = List(63)   

上述最后兩個(gè)例子中使用了map函數(shù),他對(duì)列表中的每一項(xiàng)目都適用作為參數(shù)傳入的函數(shù)之后將適用結(jié)果作為列表返回。函數(shù)則是由函數(shù)文本(s:String) => s.length或函數(shù)變量ssize來(lái)指定的。這也是閉包的一個(gè)例子,在Scala中用函數(shù)來(lái)定義閉包。任意的函數(shù)都可以作為參數(shù)來(lái)傳給別的函數(shù)。

例如前面的bar函數(shù)如下所示

  1. def bar(s: String, n: Int): Unit = for(i <- 1 to n) print(s) 

這也可以用匿名函數(shù)來(lái)定義,這次是有兩個(gè)參數(shù)且返回值是Unit的函數(shù)。

  1. scala> val f0 = (s:String, n:Int) => for(i <- 1 to n) print(s)  
  2. f0: (String, Int) => Unit =  

這個(gè)函數(shù)中用for語(yǔ)句進(jìn)行了n次循環(huán),其實(shí)還可以改寫成如下形式。

  1. def bar(s: String, n: Int): Unit = 1 to n foreach {i => print(s)} 

函數(shù)體中出現(xiàn)的{i => print(s)}就是以匿名函數(shù)形式定義的閉包。1 to n是1.to(n)的簡(jiǎn)化形式,然后將閉包作為參數(shù)傳遞給剛創(chuàng)建的Range對(duì)象的foreach方法(參數(shù)i在閉包的函數(shù)體中并沒(méi)有被使用,僅是為了語(yǔ)法需要)。

在表達(dá)式中作為占位符的下劃線

實(shí)際上,Scala中備有比匿名函數(shù)更簡(jiǎn)潔的描述方式。

如下所示,對(duì)于“(s:String) => s.length”來(lái)說(shuō),可以用“_”以“( _:String).length”形式來(lái)描述。還有可以用“(_:Int)+(_:Int)”來(lái)定義類型為“(Int, Int) => Int”的加法表達(dá)式。

  1. scala> ((_:String).length)("abcde")  
  2. res6: Int = 5 
  3. scala> ((_:Int)+(_:Int))(34)  
  4. res7: Int = 7 
  5. scala> ((_:String).length + (_:Int)) ("abc"4)  
  6. res8: Int = 7 

部分函數(shù)的定義

Scala中不僅可以用到現(xiàn)在所看到的式子來(lái)定義,還可以通過(guò)將具體的實(shí)例一排排列出后,用類似于數(shù)學(xué)中學(xué)到的映像圖的形式來(lái)描述。聲明了“f1:A=>B”之后可以認(rèn)為是定義了將類型A映像為類型B的函數(shù)f1。實(shí)際上這可以認(rèn)為是將函數(shù)定義為類Function1[A, B]的實(shí)例(圖 6-1)。

  1. def f1: Symbol=>Int = {  
  2. case 'a => 1 
  3. case 'b => 2 
  4. case 'c => 3 
  5. }  
  6. scala> f1('c)  
  7. res9: Int = 3 
  8. scala> f1('d)  
  9. scala.MatchError: 'd  
  10. at $anonfun$f1$1.apply(:8)  
  11. at $anonfun$f1$1.apply(:8)  
  12. at .(:10)  
  13. at .()  
  14. at RequestResult$.(:3)  
  15. at RequestResult$.()  
  16. at RequestResult$result()  
  17. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  18. at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)... 

圖 6-1定義為源值域與目標(biāo)值域映像的函數(shù) 

圖 6-1定義為源值域與目標(biāo)值域映像的函數(shù)

函數(shù)本來(lái)不就因該是這樣的嗎?但是問(wèn)題是,如果將函數(shù)定義域中沒(méi)有的參數(shù)傳給f1函數(shù)后將會(huì)拋出例外。為了避免這種情況在對(duì)于某一值適用函數(shù)前可以先檢查一下該值是否在定義域中。部分函數(shù)(PartialFunction)定義為我們提供了這種結(jié)構(gòu)。

  1. def f2: PartialFunction[Symbol, Int] =  
  2. {case 'a => 1; case 'b => 2case 'c => 3}  
  3. scala> for(s <- List('a, 'b, 'c, 'd)){ if( f2.isDefinedAt(s) ) println( f2(s) ) }  
  4. 1 
  5. 2 
  6. 3 

用部分函數(shù)定義了f2:A=>B函數(shù)之后,就可以在適用函數(shù)前先使用isDefinedAt(x:A)方法來(lái)確定定義域

了。所謂的部分函數(shù)就是,對(duì)于反應(yīng)源值域到目標(biāo)值域的映射的函數(shù)f:A=>B,不一定存在對(duì)應(yīng)于x<-A的f(x)。反過(guò)來(lái)如果對(duì)于任意的x<-A都存在f(x)的話,那f就稱為全函數(shù)。

Scala中方法和函數(shù)的關(guān)系

Scala即是純面向?qū)ο笳Z(yǔ)言又是函數(shù)式語(yǔ)言,給人一種朦朧的感覺(jué)。所謂的純面向?qū)ο缶褪撬械恼Z(yǔ)言元素都是作為對(duì)象來(lái)處理的。各個(gè)對(duì)象所持有的屬性不管是數(shù)還是字符串還是數(shù)組還是Person等實(shí)例都是對(duì)象。

因此,當(dāng)然函數(shù)也是對(duì)象。實(shí)際上函數(shù)f: (ArgType1,...ArgTypeN)=>ReturnTyp是以類FunctionN[ArgType1,..., ArgTypeN, ReturnType]的實(shí)例形式被定義的。N是表示參數(shù)個(gè)數(shù)的正整數(shù)。如果是1個(gè)參數(shù)的話則是Function1[ArgType1, ReturnType]。

  1. def double(n:Int):Int = n * 2 

上述函數(shù)基本上與下述定義是等同的。

  1. object double extends Function1[Int, Int] {  
  2. def apply(n: Int): Int = n * 2 
  3. }  
  4. scala> double(10)  
  5. res1: Int = 20 

那么各個(gè)對(duì)象的方法也可以稱得上對(duì)象嗎?作為測(cè)試,試著將MyFunctions對(duì)象的方法綁定于變量。

  1. scala> val f1 = MyFunctions.foo  
  2. :8: error: missing arguments for method foo in object MyFunctions;  
  3. follow this method with `_' if you want to treat it as a partially applied funct  
  4. ion  
  5. val f1 = MyFunctions.foo  

看來(lái)光是方法原樣是不能作為函數(shù)對(duì)象來(lái)處理的。實(shí)際上只要將方法簡(jiǎn)單地轉(zhuǎn)換一下就可以作為對(duì)象來(lái)使用了。在方法名后空一格加上“_”就可以了。

  1. scala> val f1 = MyFunctions.foo _  
  2. f1: (String, Int) => Int =   
  3. scala> f1("abcde"3)  
  4. res13: Int = 15 

這樣處理之后,我們就可以明白對(duì)象的方法也可以像屬性一樣作為對(duì)象來(lái)統(tǒng)一處理了。Scala語(yǔ)言在這一點(diǎn)上可以說(shuō)比Smalltalk那種純面向?qū)ο笳Z(yǔ)言還貫徹了面向?qū)ο蟮乃枷搿?/P>

高階函數(shù)和延遲評(píng)估參數(shù)

因?yàn)镾cala的函數(shù)是對(duì)象,所以不要做什么特殊處理只要將他作為參數(shù)傳給別的函數(shù)就自然而然地成為使用高階函數(shù)了。函數(shù)將別的函數(shù)作為參數(shù)來(lái)使用,所以稱之為高階函數(shù)。這時(shí)被傳遞的函數(shù)就稱為閉包。

用于List統(tǒng)一操作的函數(shù)群就是高階函數(shù)的典型例。下面的foreach函數(shù),接受了以()或{}形式定義的閉包作為參數(shù),然后將其逐一適用于接受者列表的所有元素。

  1. scala> val list = List("Scala""is""functional""language")  
  2. list: List[java.lang.String] = List(Scala, is, functional, language)  
  3. scala> list.foreach { e => println(e) }  
  4. Scala  
  5. is  
  6. functional  
  7. language  

對(duì)于同一列表list適用map函數(shù)后,對(duì)于列表list的所有元素適用s => s + “!”函數(shù)后將適用結(jié)果以列表的形式返回。這里用空格代替了調(diào)用方法的“.”,然后用( _ + “!”)替代(s => s + “!”)也是可以的。

  1. scala> list map(s => s + "!")  
  2. res15: List[java.lang.String] = List(Scala!, is!, functional!, language!)  
  3. scala> list map( _ + "!")  
  4. res16: List[java.lang.String] = List(Scala!, is!, functional!, language!)  

進(jìn)一步,Scala中除了有f1(p1:T1)這種通常的“基于值的參數(shù)傳遞(by value parameter)”,還有表示為f2(p2 => T2)的“基于名稱的參數(shù)傳遞(by name parameter)”,后者用于參數(shù)的延時(shí)評(píng)估。將這個(gè)結(jié)構(gòu)和高階函數(shù)相混合后,就可以簡(jiǎn)單地定義新的語(yǔ)言控制結(jié)構(gòu)了。下面是新語(yǔ)言結(jié)構(gòu)MyWhile的定義和使用例。

  1. def MyWhile (p: => Boolean) (s: => Unit) {  
  2. if (p) { s ; MyWhile( p )( s ) }  
  3. }  
  4. scala> var i: Int = 0 
  5. i: Int = 0 
  6. scala> MyWhile(i < 3) {i=i+1; print("World ") }  
  7. World World World  
  8. scala> MyWhile(true) {print(“World is unlimited”) }  
  9. 無(wú)限循環(huán)  

像這樣充分利用了函數(shù)式語(yǔ)言的特點(diǎn)之后,我們會(huì)驚奇地發(fā)現(xiàn)像定義DSL(特定領(lǐng)域語(yǔ)言)那樣進(jìn)行語(yǔ)言的擴(kuò)展是多么的容易和自由。

模式匹配

Scala的case語(yǔ)句非常強(qiáng)大,可以處理任何類型的對(duì)象。mach{}內(nèi)部列出了case 模式 => 語(yǔ)句。為了確保覆蓋性可以在末尾加上 _。

  1. scala> val value: Any = "string" 
  2. value: Any = string  
  3. scala> value match {  
  4. case null => println("null!")  
  5. case i: Int => println("Int: " + i)  
  6. case s: String => println("String: " + s)  
  7. case _ => println("Others")  
  8. | }  
  9. String: string  

這次匹配一下Person類的對(duì)象。

  1. scala> class Person(name:String)  
  2. defined class Person  
  3. scala> val value : Any = new Person("Zhang Fei")  
  4. value: Any = Person@e90097 
  5. scala> value match {  
  6. case null => println("null!")  
  7. case i: Int => println("Int: " + i)  
  8. case s: String => println("String: " + s)  
  9. case _ => println("Others")  
  10. | }  
  11. Others  

Case類

在Scala中模式匹配的不僅是對(duì)象,對(duì)象的屬性和類型等也可以作為模式來(lái)匹配。

例如,假設(shè)想匹配Person類,一般情況下最多就是指定“_ : Person”來(lái)匹配屬于Person類的對(duì)象了。

  1. scala> val value : Any = new Person("Zhang Fei")  
  2. value: Any = Person@1e3c2c6 
  3. scala> value match {  
  4. case _ : Person => println("person: who")  
  5. case _ => println("others: what")  
  6. | }  
  7. person: who  

不過(guò)如果使用了Case類之后,對(duì)象內(nèi)的公有屬性變得也可以匹配了。定義類時(shí)只要把“class”換成“case class”之后,編譯器就會(huì)自動(dòng)定義和生成同名的單例對(duì)象。并且在該單例對(duì)象中自動(dòng)定義了返回該類實(shí)例的apply方法,以及返回以構(gòu)造函數(shù)的參數(shù)為參數(shù)的Some類型(范型)對(duì)象的unapply(或unapplySeq)方法。并且,還自動(dòng)定義了equals、hashCode和toString方法。

定義apply方法的效果是,只要定義好某個(gè)Case類之后,就可以用“類名(參數(shù)列表)”的形式來(lái)創(chuàng)建對(duì)象了。定義unapply方法后的效果是,可以在case語(yǔ)句中以Case類的構(gòu)造函數(shù)的參數(shù)(對(duì)象屬性)來(lái)作為匹配目標(biāo)了。

  1. scala> case class Person(name:String) //定義Case類Person  
  2. defined class Person  
  3. scala> val value : Any = Person("Zhang Fei"//不用new就可以創(chuàng)建對(duì)象  
  4. value: Any = Person(Zhang Fei)  
  5. scala> value match {  
  6. case Person(ns) => println("person:" + ns) //可以將Person的屬性作為匹配目標(biāo)  
  7. case _ => println("others: what")  
  8. | }  
  9. person:Zhang Fei //Person的屬性name將會(huì)被抽取出來(lái)  

下面是將將整數(shù)N(v)、Add(l, r)和Mult(l, r)組合后來(lái)變現(xiàn)四則運(yùn)算Term。由于是以case形式定義的類,請(qǐng)注意一下在創(chuàng)建Term對(duì)象時(shí),不用new就可以直接調(diào)用N(5)、Add(…)、Mult(…)實(shí)現(xiàn)了。如此使用Scala的模式匹配功能后就可以很方便地實(shí)現(xiàn)對(duì)象的解析工作了。

  1. abstract class Term  
  2. case class N (v :Int) extends Term  
  3. case class Add(l :Term, r :Term) extends Term  
  4. case class Mult(l :Term, r :Term) extends Term  
  5. def eval(t :Term) :Int = t match {  
  6. case N (v) => v  
  7. case Add(l, r) => eval(l) + eval(r)  
  8. case Mult(l, r) => eval(l) * eval(r)  
  9. }  
  10. scala> eval(Mult(N (5), Add(N (3), N (4))))  
  11. res7:Int = 35 // 5 * (3 + 4)  

附帶說(shuō)一下,上述的Term類可以認(rèn)為是作為N、Add和Mult類的抽象數(shù)據(jù)類型來(lái)定義的。

將模式匹配與for語(yǔ)句組合

下面就看一下將模式匹配與for語(yǔ)句組合在一起的技巧。

  1. scala> val list = List((1"a"), (2"b"), (3"c"), (1"z"), (1"a"))  
  2. list: List[(Int, java.lang.String)] = List((1,a), (2,b), (3,c), (1,z), (1,a)) 

這時(shí)在<-前面寫的是像(1, x)一樣的模板。

  1. scala> for( (1, x) <- list ) yield (1, x)  
  2. res6: List[(Int, java.lang.String)] = List((1,a), (1,z), (1,a)) 

而且非常令人驚奇的是<-前面沒(méi)有變量也是可以的。在<-之前寫上(1, “a”)之后,for語(yǔ)句也可以正常地循環(huán)并且正確地返回了兩個(gè)元素。

  1. scala> for( (1"a") <- list ) yield (1"a")  
  2. res7: List[(Int, java.lang.String)] = List((1,a), (1,a)) 

還有在使用Option[T]類來(lái)避免判斷null的情況下,傳入List[Option[T]]類型的列表時(shí),不用顯示的判斷是否是Some還是None就可以一下子返回正確的結(jié)果了。

  1. scala> val list = List(Some(1), None, Some(3), None, Some(5))  
  2. list: List[Option[Int]] = List(Some(1), None, Some(3), None, Some(5))  
  3. scala> for(Some(v) <- list) println(v)  
  4. 1 
  5. 3 
  6. 5 

接著用以下的例子看一下組合模式匹配和for語(yǔ)句之后所產(chǎn)生的威力。

  1. scala> val list = List(1"two", Some(3), 4"five"6.07)  
  2. list: List[Any] = List(1, two, Some(3), 4, five, 6.07

對(duì)上述例表中的元素對(duì)象類型進(jìn)行判別后再分類一下吧。模式匹配里不僅可以使用值來(lái)作為模式,從下例可知模式還具有對(duì)Some(x)形式中的x也起作用的靈活性。

  1. for(x <- list){ x match{  
  2. case x:Int => println("integer " + x)  
  3. case x:String => println("string " + x)  
  4. case Some(x) => println("some " + x)  
  5. case _ => println("else " + x)  
  6. } }  
  7. scala> for(x <- list){ x match{  
  8. case x:Int => println("integer " + x)  
  9. case x:String => println("string " + x)  
  10. case Some(x) => println("some " + x)  
  11. case _ => println("else " + x)  
  12. | } }  
  13. integer 1 
  14. string two  
  15. some 3 
  16. integer 4 
  17. string five  
  18. else 6.0 
  19. integer 7 

結(jié)束語(yǔ)

看了本文之后大家覺(jué)得怎么樣呀?應(yīng)該享受了Scala所具備的,將面向?qū)ο笫胶秃瘮?shù)式語(yǔ)言功能充分融合的能力,以及高階函數(shù)和模式匹配功能了吧。

Scala語(yǔ)法的初步介紹就到本講為止了,接下來(lái)的講座將介紹一下Scala語(yǔ)言更深入的部分。包括隱式轉(zhuǎn)換、范型和單子等有趣的話題。

【編輯推薦】

  1. Scala講座:面向?qū)ο蠛秃瘮?shù)式的特點(diǎn)總結(jié)
  2. Scala講座:函數(shù)式編程處理樹結(jié)構(gòu)數(shù)據(jù)
  3. Scala講座:編程的思考方法
  4. Scala講座:將函數(shù)作為第一類對(duì)象來(lái)處理
  5. Scala講座:全局變量問(wèn)題的解決
責(zé)任編輯:book05 來(lái)源: JavaEye博客
相關(guān)推薦

2009-09-27 15:29:00

Scala講座面向?qū)ο?/a>Scala

2009-09-27 15:23:00

Scala講座函數(shù)式編程Scala

2009-12-11 10:42:00

Scala講座類定義構(gòu)造函數(shù)

2009-09-24 09:41:00

Scala講座Scala

2010-01-28 14:51:24

Scala后函數(shù)式

2009-12-11 10:43:00

Scala講座操作符函數(shù)

2009-09-24 09:28:00

Scala講座全局變量scala

2010-03-11 10:34:22

Scala

2009-12-11 10:45:00

Scala講座類型系統(tǒng)功能

2009-07-08 12:43:59

Scala ServlScala語(yǔ)言

2009-07-21 17:16:34

Scala函數(shù)式指令式

2009-09-24 09:38:00

Scala講座第一類對(duì)象scala

2020-10-31 17:33:18

Scala語(yǔ)言函數(shù)

2009-07-08 16:10:24

Scala簡(jiǎn)介面向?qū)ο?/a>函數(shù)式

2009-12-11 10:43:00

Scala講座混入多重繼承類型層次

2009-07-09 00:25:00

Scala函數(shù)式

2009-06-09 13:18:56

Scala函數(shù)式命令式

2009-07-22 07:42:00

Scala偏應(yīng)用函數(shù)

2009-06-26 14:42:08

2009-07-22 07:57:00

ScalaCurry化函數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: www.日韩 | 91视频国产区 | 在线免费观看视频黄 | 午夜精品久久久久99蜜 | 中文字幕免费视频 | 一区二区三区亚洲 | 久久精品国产一区二区电影 | 成人免费激情视频 | 精品国产一区二区三区性色av | 91久久久久久久久久久 | www.99热这里只有精品 | 在线成人免费视频 | 精品日韩在线观看 | 美女黄视频网站 | 91精品观看| 日韩一区二区在线视频 | 精品久久影院 | av在线播放网址 | 欧美日韩网站 | 亚洲成av人片在线观看 | 国产精品久久久久久久粉嫩 | 久久久久久久一区二区 | 亚洲欧美中文日韩在线v日本 | 国产高清一区二区三区 | 国产精品永久免费观看 | 国产高清在线观看 | 精品美女视频在线观看免费软件 | 成人激情视频在线播放 | 国产91在线观看 | 国产欧美精品 | 天天干天天操天天射 | 欧美国产中文字幕 | 蜜桃视频一区二区三区 | 一级毛片视频免费观看 | 国产激情一区二区三区 | 成人在线欧美 | 久久综合婷婷 | 日本激情一区二区 | 日韩精品在线视频 | 91大神新作在线观看 | 中文字幕精品一区二区三区精品 |