国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

函數(shù)式編程與面向?qū)ο缶幊蘙4]:Scala的類型關(guān)聯(lián)Type Alias

wupengyu / 835人閱讀

摘要:函數(shù)式編程與面向?qū)ο缶幊痰念愋完P(guān)聯(lián)之劍目錄類型關(guān)聯(lián)關(guān)鍵字里的類型,除了在定義時(shí)會產(chǎn)生類型,還可以通過關(guān)鍵字來聲明類型。復(fù)合類型與關(guān)鍵字這種形式的類型稱為復(fù)合類型或者也叫交集類型。

函數(shù)式編程與面向?qū)ο缶幊蘙4]:Scala的類型關(guān)聯(lián)Type Alias

之劍 2016.5.4 23:55:19


類型關(guān)聯(lián) Type Alias type關(guān)鍵字

scala里的類型,除了在定義class,trait,object時(shí)會產(chǎn)生類型,還可以通過type關(guān)鍵字來聲明類型。

type相當(dāng)于聲明一個(gè)類型別名:

object TestMatrix extends App{  
  type IntList = List[Int]
  //接下來就可以這樣使用它:
  type Matrix = List[IntList]

  val m = Matrix( IntList(1,2,3),
                  IntList(1,2,3),
                  IntList(1,2,3))
}
scala> type IntList=List[Int]
defined type alias IntList

這種給類型一個(gè)別名的特性只是一個(gè)小糖豆,不太甜,真正有趣的是給一類操作命名(聯(lián)想C#中定義delegate)。

比如這樣:

type PersonPredicate = Person => Boolean

接受一個(gè)Person,返回一個(gè)Boolean,我們把這一類用來判斷一個(gè)人是否符合某個(gè)條件的操作統(tǒng)稱為PersonPredicate。

然后我們可以定義以下predicate:

val teenagerPred: PersonPredicate = person => person.age < 20

然后前面寫過的teenagers方法就可以這樣重新定義:

  def teenagers(people: People): People = {
    people.filter(teenagerPred)
  }

按照這個(gè)思路下去,我們就可以開始composite functions了。比如說,我們跟人收稅,就可以這么做:

    

  type Tax = Person => Double
  val incomeTax: Tax = person => person.income * 5 / 100
  val kejuanzaTax: Tax = person => person.income * 20 / 100
  def giveMeYourMoney(p: Person) = {
    calculateTax(p, List(incomeTax, kejuanzaTax))
  }
  def calculateTax(person: Person, taxes: List[Tax]): Double = {
    taxes.foldLeft(0d) {
      (acc, curTax) => acc + curTax(person)
    }
  }

總結(jié)一下type alia這個(gè)糖衣:

一個(gè)類型的type alias,類似于這樣的:type t = x。編譯器將在所有使用到t的地方把t替換為x。

對于一種操作的type alias,編譯器將會根據(jù)參數(shù)列表和返回值類型的不同將其替換為對應(yīng)的Function0,Function1,Function2 …… 一直到Function22。

如果我們真的定義一個(gè)超過22個(gè)參數(shù)的操作會如何呢?

  type twentyThree = (
      String, String, String, String,
      String, String, String, String,
      String, String, String, String,
      String, String, String, String,
      String, String, String, String,
      String, String, String
    ) => String
    

Scala編譯器會直接告訴我們: type Function23 is not a member of package scala

結(jié)構(gòu)類型

結(jié)構(gòu)類型(structural type)為靜態(tài)語言增加了部分動(dòng)態(tài)特性,使得參數(shù)類型不再拘泥于某個(gè)已命名的類型,只要參數(shù)中包含結(jié)構(gòu)中聲明的方法或值即可。舉例來說,java里對所有定義了close方法的抽象了一個(gè)Closable接口,然后再用Closable類型約束參數(shù),而scala里可以不要求參數(shù)必須繼承自Closable接口只需要包含close方法;如下:

scala> def free( res: {def close():Unit} ) { 
            res.close 
        }

scala> free(new { def close()=println("closed") })
closed

也可以通過type在定義類型時(shí),將其聲明為結(jié)構(gòu)類型

scala> type X = { def close():Unit }
defined type alias X

scala> def free(res:X) = res.close

scala> free(new { def close()=println("closed") })
closed

上面?zhèn)魅雲(yún)?shù)時(shí),都是傳入一個(gè)實(shí)現(xiàn)close方法的匿名類,如果某個(gè)類/單例中實(shí)現(xiàn)了close方法,也可以直接傳入

scala> object A { def close() {println("A closed")} }

scala> free(A)
A closed

scala> class R { def close()=print("ok") }

scala> val r = new R

scala> free(r)
ok

結(jié)構(gòu)類型還可以用在稍微復(fù)雜一點(diǎn)的“復(fù)合類型”中,比如:

scala> trait X1; trait X2;

scala> def test(x: X1 with X2 { def close():Unit } ) = x.close

上面聲明test方法參數(shù)的類型為:

X1 with X2 { def close():Unit }

表示參數(shù)需要符合特質(zhì)X1和X2同時(shí)也要有定義close方法。

復(fù)合類型與with關(guān)鍵字
class A extends (B with C with D with E)

T1 with T2 with T3 …

這種形式的類型稱為復(fù)合類型(compound type)或者也叫交集類型(intersection type)。

跟結(jié)構(gòu)類型類似,可以在一個(gè)方法里聲明類型參數(shù)時(shí)使用復(fù)合類型:

scala> trait X1; trait X2;

scala> def test(x: X1 with X2) = {println("ok")}
test: (x: X1 with X2)Unit

scala> test(new X1 with X2)
ok

scala> object A extends X1 with X2

scala> test(A)
ok

也可以通過 type 聲明:


scala> type X = X1 with X2
defined type alias X

scala> def test(x:X) = println("OK")
test: (x: X)Unit

scala> class A extends X1 with X2

scala> val a = new A

scala> test(a)
OK


結(jié)構(gòu)類型

結(jié)構(gòu)類型:定義方法或者表達(dá)式時(shí),要求傳參具有某種行為,但又不想使用類,或者接口去限制,可以使用結(jié)構(gòu)類型。

    class Structural { def open()=print("A class instance Opened") }

    object Structural__Type {

      def main(args: Array[String]){
        init(new { def open()=println("Opened") }) //創(chuàng)建了一個(gè)匿名對象,實(shí)現(xiàn)open方法
        type X = { def open():Unit } //將右邊的表達(dá)式命名為一個(gè)別名
        def init(res:X) = res.open
        init(new { def open()=println("Opened again") })
        
        object A { def open() {println("A single object Opened")} } //創(chuàng)建的單例對象里面也必須實(shí)現(xiàn)open方法
        init(A)
        
        val structural = new Structural
        init(structural)
        
      }

      def init( res: {def open():Unit} ) { //要求傳進(jìn)來的res對象具有open方法,不限制類型
                res.open
            }
    }

Scala復(fù)合類型解析:




    trait Compound_Type1;
    trait Compound_Type2;
    class Compound_Type extends Compound_Type1 with Compound_Type2
    object Compound_Type {
      def compound_Type(x: Compound_Type1 with Compound_Type2) = {println("Compound Type in global method")} //限制參數(shù)x即是Type1的類型,也是Type2的類型
      def main(args: Array[String]) {
        
        compound_Type(new Compound_Type1 with Compound_Type2) //匿名方式,結(jié)果:Compound Type in global method
        object compound_Type_oject extends Compound_Type1 with Compound_Type2 //object繼承方式,trait混入object對象中
        compound_Type(compound_Type_oject) //結(jié)果都一樣,Compound Type in global method
        
        type compound_Type_Alias = Compound_Type1 with Compound_Type2 //定義一個(gè)type別名
        def compound_Type_Local(x:compound_Type_Alias) = println("Compound Type in local method") //使用type別名進(jìn)行限制
        val compound_Type_Class = new Compound_Type
        compound_Type_Local(compound_Type_Class) //結(jié)果:Compound Type in local method
        
        type Scala = Compound_Type1 with Compound_Type2 { def init():Unit } //type別名限制即是Type1,也是Type2,同時(shí)還要實(shí)現(xiàn)init方法
      }

    }
Infix Type

Infix Type:中值類型,允許帶有兩個(gè)參數(shù)的類型。


    object Infix_Types {

      def main(args: Array[String]) {
        
        object Log { def >>:(data:String):Log.type = { println(data); Log } }
        "Hadoop" >>: "Spark" >>: Log //右結(jié)合,先打印出Spark,再打印出Hadoop
        
         val list = List()
         val newList = "A" :: "B" :: list //中值表達(dá)式
         println(newList)
        
        class Infix_Type[A,B] //中值類型是帶有兩個(gè)類型參數(shù)的類型
        val infix: Int Infix_Type String = null //此時(shí)A是Int,B為String,具體類型名寫在兩個(gè)類型中間
        val infix1: Infix_Type[Int, String] = null //和這種方式等價(jià)
        
        case class Cons(first:String,second:String) //中值類型
        val case_class = Cons("one", "two")
        case_class match { case "one" Cons "two" => println("Spark!!!") } //unapply
        
      }

    }


self-type


    class Self {
        self => //self是this別名
        val tmp="Scala"
        def foo = self.tmp + this.tmp
    }
    trait S1
    class S2 { this:S1 => } //限定:實(shí)例化S2時(shí),必須混入S1類型
    class S3 extends S2 with S1
    class s4 {this:{def init():Unit} =>} //也能用于結(jié)構(gòu)類型限定

    trait T { this:S1 => } //也能用于trait
    object S4 extends T with S1
    object Self_Types {

      def main(args: Array[String]) {
        class Outer { outer =>
         val v1 = "Spark"
         class Inner {
         println(outer.v1)  //使用外部類的屬性
         }
        }
        val c = new S2 with S1 //實(shí)例化S2時(shí)必須混入S1類型
      }

    }



---


關(guān)于作者: 陳光劍,江蘇東海人, 號行走江湖一劍客,字之劍。程序員,詩人, 作家

http://universsky.github.io/?


---


  


  

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/65874.html

相關(guān)文章

  • 函數(shù)入門(什么是函數(shù)編程)

    摘要:第一節(jié)函數(shù)式范式什么是函數(shù)式編程函數(shù)式編程英語或稱函數(shù)程序設(shè)計(jì),又稱泛函編程,是一種編程范型,它將電腦運(yùn)算視為數(shù)學(xué)上的函數(shù)計(jì)算,并且避免使用程序狀態(tài)以及易變對象。 第一節(jié) 函數(shù)式范式 1. 什么是函數(shù)式編程 函數(shù)式編程(英語:functional programming)或稱函數(shù)程序設(shè)計(jì),又稱泛函編程,是一種編程范型,它將電腦運(yùn)算視為數(shù)學(xué)上的函數(shù)計(jì)算,并且避免使用程序狀態(tài)以及易變對...

    StonePanda 評論0 收藏0
  • 函數(shù)編程面向對象編程[1]: Lambda表達(dá) 函數(shù)柯里化 高階函數(shù)

    摘要:函數(shù)式編程與面向?qū)ο缶幊瘫磉_(dá)式函數(shù)柯里化高階函數(shù)之劍什么是表達(dá)式例子定義表達(dá)式是一個(gè)匿名函數(shù),表達(dá)式基于數(shù)學(xué)中的演算得名,直接對應(yīng)于其中的抽象,是一個(gè)匿名函數(shù),即沒有函數(shù)名的函數(shù)。 函數(shù)式編程與面向?qū)ο缶幊蘙1]: Lambda表達(dá)式 函數(shù)柯里化 高階函數(shù).md 之劍 2016.5.2 11:19:09 什么是lambda表達(dá)式 例子 For example, in Lisp the...

    張金寶 評論0 收藏0
  • 函數(shù)編程面向對象編程[2]: 靜態(tài)類型語言表達(dá)力 靜態(tài)類型語言動(dòng)態(tài)類型語言

    摘要:動(dòng)態(tài)類型語言的表達(dá)力動(dòng)態(tài)語言通常更方便開發(fā)較小的項(xiàng)目,因?yàn)榭梢詿o需聲明類型而節(jié)省了很多麻煩。 函數(shù)式編程與面向?qū)ο缶幊蘙2]: 靜態(tài)類型語言的表達(dá)力 靜態(tài)類型語言與動(dòng)態(tài)類型語言 之劍 2016.5.3 21:43:20 像Java或者C#這樣強(qiáng)類型的準(zhǔn)靜態(tài)語言在實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯、開發(fā)大型商業(yè)系統(tǒng)、以及那些生命周期很長的應(yīng)用中也有著非常強(qiáng)的優(yōu)勢 下面我們就來學(xué)習(xí)一下這些知識. 有三...

    Betta 評論0 收藏0
  • JVM 平臺上各種語言開發(fā)指南[z]

    摘要:我們的目標(biāo)是建立對每一種語言的認(rèn)識,它們是如何進(jìn)化的,未來將走向何方。有點(diǎn)的味道是堅(jiān)持使用動(dòng)態(tài)類型,但唯一還收到合理擁泵的編程語言,然而一些在企業(yè)的大型團(tuán)隊(duì)中工作的開發(fā)者擇認(rèn)為這會是的一個(gè)缺陷。 為什么我們需要如此多的JVM語言? 在2013年你可以有50中JVM語言的選擇來用于你的下一個(gè)項(xiàng)目。盡管你可以說出一大打的名字,你會準(zhǔn)備為你的下一個(gè)項(xiàng)目選擇一種新的JVM語言么? 如今借助來自...

    phodal 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來學(xué)習(xí)一門新編程語言吧!

    摘要:入門,第一個(gè)這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數(shù)式編程語言,它的代碼運(yùn)行在之上。它通過編輯類工具,帶來了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來了,總結(jié)過去的 2017,相信小伙們一定有很多收獲...

    caspar 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<