<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                課程內容: [TOC=2,3] ## apply 方法 當類或對象有一個主要用途的時候,apply方法為你提供了一個很好的語法糖。 ~~~ scala> class Foo {} defined class Foo scala> object FooMaker { | def apply() = new Foo | } defined module FooMaker scala> val newFoo = FooMaker() newFoo: Foo = Foo@5b83f762 ~~~ 或 ~~~ scala> class Bar { | def apply() = 0 | } defined class Bar scala> val bar = new Bar bar: Bar = Bar@47711479 scala> bar() res8: Int = 0 ~~~ 在這里,我們實例化對象看起來像是在調用一個方法。以后會有更多介紹! ## 單例對象 單例對象用于持有一個類的唯一實例。通常用于工廠模式。 ~~~ object Timer { var count = 0 def currentCount(): Long = { count += 1 count } } ~~~ 可以這樣使用: ~~~ scala> Timer.currentCount() res0: Long = 1 ~~~ 單例對象可以和類具有相同的名稱,此時該對象也被稱為“伴生對象”。我們通常將伴生對象作為工廠使用。 下面是一個簡單的例子,可以不需要使用’new’來創建一個實例了。 ~~~ class Bar(foo: String) object Bar { def apply(foo: String) = new Bar(foo) } ~~~ ## 函數即對象 在Scala中,我們經常談論對象的函數式編程。這是什么意思?到底什么是函數呢? 函數是一些特質的集合。具體來說,具有一個參數的函數是Function1特質的一個實例。這個特征定義了`apply()`語法糖,讓你調用一個對象時就像你在調用一個函數。 ~~~ scala> object addOne extends Function1[Int, Int] { | def apply(m: Int): Int = m + 1 | } defined module addOne scala> addOne(1) res2: Int = 2 ~~~ 這個Function特質集合下標從0開始一直到22。為什么是22?這是一個主觀的魔幻數字(magic number)。我從來沒有使用過多于22個參數的函數,所以這個數字似乎是合理的。 apply語法糖有助于統一對象和函數式編程的二重性。你可以傳遞類,并把它們當做函數使用,而函數本質上是類的實例。 這是否意味著,當你在類中定義一個方法時,得到的實際上是一個Function*的實例?不是的,在類中定義的方法是方法而不是函數。在repl中獨立定義的方法是Function*的實例。 類也可以擴展Function,這些類的實例可以使用()調用。 ~~~ scala> class AddOne extends Function1[Int, Int] { | def apply(m: Int): Int = m + 1 | } defined class AddOne scala> val plusOne = new AddOne() plusOne: AddOne = <function1> scala> plusOne(1) res0: Int = 2 ~~~ 可以使用更直觀快捷的`extends (Int => Int)`代替`extends Function1[Int, Int]` ~~~ class AddOne extends (Int => Int) { def apply(m: Int): Int = m + 1 } ~~~ ## 包 你可以將代碼組織在包里。 ~~~ package com.twitter.example ~~~ 在文件頭部定義包,會將文件中所有的代碼聲明在那個包中。 值和函數不能在類或單例對象之外定義。單例對象是組織靜態函數(static function)的有效工具。 ~~~ package com.twitter.example object colorHolder { val BLUE = "Blue" val RED = "Red" } ~~~ 現在你可以直接訪問這些成員 ~~~ println("the color is: " + com.twitter.example.colorHolder.BLUE) ~~~ 注意在你定義這個對象時Scala解釋器的返回: ~~~ scala> object colorHolder { | val Blue = "Blue" | val Red = "Red" | } defined module colorHolder ~~~ 這暗示了Scala的設計者是把對象作為Scala的模塊系統的一部分進行設計的。 ## 模式匹配 這是Scala中最有用的部分之一。 匹配值 ~~~ val times = 1 times match { case 1 => "one" case 2 => "two" case _ => "some other number" } ~~~ 使用守衛進行匹配 ~~~ times match { case i if i == 1 => "one" case i if i == 2 => "two" case _ => "some other number" } ~~~ 注意我們是怎樣將值賦給變量’i’的。 在最后一行指令中的`_`是一個通配符;它保證了我們可以處理所有的情況。 否則當傳進一個不能被匹配的數字的時候,你將獲得一個運行時錯誤。我們以后會繼續討論這個話題的。 **參考**?Effective Scala 對[什么時候使用模式匹配](http://twitter.github.com/effectivescala/#Functional programming-Pattern matching)?和?[模式匹配格式化](http://twitter.github.com/effectivescala/#Formatting-Pattern matching)的建議. A Tour of Scala 也描述了?[模式匹配](http://www.scala-lang.org/node/120) ### 匹配類型 你可以使用?`match`來分別處理不同類型的值。 ~~~ def bigger(o: Any): Any = { o match { case i: Int if i < 0 => i - 1 case i: Int => i + 1 case d: Double if d < 0.0 => d - 0.1 case d: Double => d + 0.1 case text: String => text + "s" } } ~~~ ### 匹配類成員 還記得我們之前的計算器嗎。 讓我們通過類型對它們進行分類。 一開始會很痛苦。 ~~~ def calcType(calc: Calculator) = calc match { case _ if calc.brand == "hp" && calc.model == "20B" => "financial" case _ if calc.brand == "hp" && calc.model == "48G" => "scientific" case _ if calc.brand == "hp" && calc.model == "30B" => "business" case _ => "unknown" } ~~~ (⊙o⊙)哦,太痛苦了。幸好Scala提供了一些應對這種情況的有效工具。 ## 樣本類 Case Classes 使用樣本類可以方便得存儲和匹配類的內容。你不用new關鍵字就可以創建它們。 ~~~ scala> case class Calculator(brand: String, model: String) defined class Calculator scala> val hp20b = Calculator("hp", "20b") hp20b: Calculator = Calculator(hp,20b) ~~~ 樣本類基于構造函數的參數,自動地實現了相等性和易讀的toString方法。 ~~~ scala> val hp20b = Calculator("hp", "20b") hp20b: Calculator = Calculator(hp,20b) scala> val hp20B = Calculator("hp", "20b") hp20B: Calculator = Calculator(hp,20b) scala> hp20b == hp20B res6: Boolean = true ~~~ 樣本類也可以像普通類那樣擁有方法。 ###### 使用樣本類進行模式匹配 case classes are designed to be used with pattern matching. Let’s simplify our calculator classifier example from earlier. 樣本類就是被設計用在模式匹配中的。讓我們簡化之前的計算器分類器的例子。 ~~~ val hp20b = Calculator("hp", "20B") val hp30b = Calculator("hp", "30B") def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel) } ~~~ 最后一句也可以這樣寫 ~~~ case Calculator(_, _) => "Calculator of unknown type" ~~~ 或者我們完全可以不將匹配對象指定為Calculator類型 ~~~ case _ => "Calculator of unknown type" ~~~ 或者我們也可以將匹配的值重新命名。 ~~~ case c@Calculator(_, _) => "Calculator: %s of unknown type".format(c) ~~~ ## 異常 Scala中的異常可以在try-catch-finally語法中通過模式匹配使用。 ~~~ try { remoteCalculatorService.add(1, 2) } catch { case e: ServerIsDownException => log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.") } finally { remoteCalculatorService.close() } ~~~ `try`也是面向表達式的 ~~~ val result: Int = try { remoteCalculatorService.add(1, 2) } catch { case e: ServerIsDownException => { log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.") 0 } } finally { remoteCalculatorService.close() } ~~~ 這并不是一個完美編程風格的展示,而只是一個例子,用來說明try-catch-finally和Scala中其他大部分事物一樣是表達式。 當一個異常被捕獲處理了,finally塊將被調用;它不是表達式的一部分。 Built at?[@twitter](http://twitter.com/twitter)?by?[@stevej](http://twitter.com/stevej),?[@marius](http://twitter.com/marius), and?[@lahosken](http://twitter.com/lahosken)?with much help from?[@evanm](http://twitter.com/evanm),?[@sprsquish](http://twitter.com/sprsquish),?[@kevino](http://twitter.com/kevino),?[@zuercher](http://twitter.com/zuercher),?[@timtrueman](http://twitter.com/timtrueman),?[@wickman](http://twitter.com/wickman), and[@mccv](http://twitter.com/mccv); Russian translation by?[appigram](https://github.com/appigram); Chinese simple translation by?[jasonqu](https://github.com/jasonqu); Korean translation by?[enshahar](https://github.com/enshahar); Licensed under the?[Apache License v2.0](http://www.apache.org/licenses/LICENSE-2.0).
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看