<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      kotlin函數和Lambda表達式——>函數

      函數:

      1.函數聲明

        kotlin中的函數使用fun關鍵字聲明:

      fun double(x: Int): Int {
           return 2 * x
      }

      2.函數用法

        調用函數使用傳統的方法:

      val result = double(2)

        調用成員函數使用點表示法:

      Stream().read() // 創建類 Stream 實例并調用 read()

      3. 參數

        函數參數使用 Pascal 表示法定義,即 name: type。參數用逗號隔開。每個參數必須有顯式類型:

      fun powerOf(number: Int, exponent: Int) { /*......*/ }

      4.默認參數

        函數參數可以有默認值,當省略相應的參數時使用默認值。與其他語言相比,這可以減少重載數量

      fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) { /*......*/ }

        默認值通過類型后面的 = 及給出的值來定義

        覆蓋方法總是使用與基類型方法相同的默認參數值。當覆蓋一個帶有默認參數值的方法時,必須從簽名 中省略默認參數值:

      open class A {
          open fun foo(i: Int = 10) { /*......*/ }
      }
      
      class B : A() {
          override fun foo(i: Int) { /*......*/ } // 不能有默認值
      }

        如果一個默認參數在一個無默認值的參數之前,那么該默認值只能通過使用具名參數調用該函數來使 用:

      fun foo(bar: Int = 0, baz: Int) { /*......*/ } 
      foo(baz = 1) // 使用默認值 bar = 0

        如果在默認參數之后的最后一個參數是 lambda 表達式,那么它既可以作為具名參數在括號內傳入,也 可以在括號外傳入

      fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { /*......*/ }
      
      foo(1) { println("hello") } // 使用默認值 baz = 1
      foo(qux = { println("hello") }) // 使用兩個默認值 bar = 0 與 baz = 1 foo { println("hello") } // 使用兩個默認值 bar = 0 與 baz = 1

      5.具名參數

        可以在調用函數時使用具名的函數參數。當一個函數有大量的參數或默認參數時這會非常方便。

        給定以下函數:

      fun reformat(str: String,
                   normalizeCase: Boolean = true,
                   upperCaseFirstLetter: Boolean = true, 
                   divideByCamelHumps: Boolean = false,
                   wordSeparator: Char = ' ') {
      /*......*/
      }

        我們可以使用默認參數來調用它:

      reformat(str)

        然而,當使用非默認參數調用它時,該調用看起來就像:

      reformat(str, true, true, false, '_')

        使用具名參數我們可以使代碼更具有可讀性:

      reformat(str,
          normalizeCase = true,
          upperCaseFirstLetter = true,
          divideByCamelHumps = false,
          wordSeparator = '_'
      )

        并且如果我們不需要所有的參數:

      reformat(str, wordSeparator = '_')

        當一個函數調用混用位置參數與具名參數時,所有位置參數都要放在第一個具名參數之前。例如,允許

      調用 f(1, y = 2) 但不允許 f(x = 1, 2)。

        可以通過使用星號操作符將可變數量參數(vararg)以具名形式傳入:

      fun foo(vararg strings: String) { /*......*/ } 
      
      foo(strings = *arrayOf("a", "b", "c"))
      
      //對于 JVM 平臺:在調用 Java 函數時不能使用具名參數語法,因為 Java 字節碼并不總是保留函數 參數的名稱。

       

      6.返回Unit的函數

        如果一個函數不返回任何有用的值,它的返回類型是 Unit 。Unit 是一種只有一個值? Unit 的類 型。這個值不需要顯式返回

      fun printHello(name: String?): Unit {
          if (name != null)
              println("Hello $name") else
              println("Hi there!")
      // `return Unit` 或者 `return` 是可選的
      }

        Unit 返回類型聲明也是可選的。上面的代碼等同于:

      fun printHello(name: String?) { ...... }

      7.單表達式函數

        當函數返回單個表達式時,可以省略花括號并且在 = 符號之后指定代碼體即可:

      fun double(x: Int): Int = x * 2

        當返回值類型可由編譯器推斷時,顯式聲明返回類型是可選的:

      fun double(x: Int) = x * 2

      8.顯示返回類型

        具有塊代碼體的函數必須始終顯式指定返回類型,除非他們旨在返回 Unit,在這種情況下它是可選 的。Kotlin 不推斷具有塊代碼體的函數的返回類型,因為這樣的函數在代碼體中可能有復雜的控制流,

      并且返回類型對于讀者(有時甚至對于編譯器)是不明顯的。

      9.可變數量的參數(Varargs)

        函數的參數(通常是最后一個)可以用 vararg 修飾符標記:

      fun <T> asList(vararg ts: T): List<T> {
          val result = ArrayList<T>()
          for (t in ts) // ts is an Array
              result.add(t) 
          return result
      }

        允許將可變數量的參數傳遞給函數:

      val list = asList(1, 2, 3)

        在函數內部,類型 T 的 vararg 參數的可?方式是作為 T 數組,即上例中的 ts 變量具有類型Array <out T>。

        只有一個參數可以標注為 vararg 。如果 vararg 參數不是列表中的最后一個參數,可以使用具名參數語法傳遞其后的參數的值,或者,如果參數具有函數類型,則通過在括號外部傳一個 lambda。

        當我們調用 vararg -函數時,我們可以一個接一個地傳參,例如 asList(1, 2, 3) ,或者,如果我們已經有一個數組并希望將其內容傳給該函數,我們使用伸展(spread)操作符(在數組前面加 * ):

      val a = arrayOf(1, 2, 3)
      val list = asList(-1, 0, *a, 4)

      10.中綴表示法

      //標有 infix 關鍵字的函數也可以使用中綴表示法(忽略該調用的點與圓括號)調用。中綴函數必須滿足 以下要求:
      //— 它們必須是成員函數或擴展函數;
      //— 它們必須只有一個參數;
      //— 其參數不得接受可變數量的參數且不能有默認值。
      
      infix fun Int.shl(x: Int): Int { ...... } 
      
      // 用中綴表示法調用該函數
      1 shl 2
      
      // 等同于這樣
      1.shl(2)
      
      //中綴函數調用的優先級低于算術操作符、類型轉換以及 rangeTo 操作符。以下表達式是等價 的:
      //— 1 shl 2 + 3等價于1 shl (2 + 3)
      //— 0 until n * 2等價于0 until (n * 2)
      //— xs union ys as Set<*>等價于xs union (ys as Set<*>)
      //另一方面,中綴函數調用的優先級高于布爾操作符 && 與 ||、is- 與 in- 檢測以及其他一些操 作符。這些表達式也是等價的:
      //— a && b xor c等價于a && (b xor c) 
      //— a xor b in c等價于(a xor b) in c

        請注意,中綴函數總是要求指定接收者與參數。當使用中綴表示法在當前接收者上調用方法時,需要顯 式使用 this ;不能像常規方法調用那樣省略。這是確保非模糊解析所必需的

      class MyStringCollection {
          infix fun add(s: String) { /*......*/
          }
      
          fun build() {
              this add "abc"// 正確 
              add("abc")// 正確
              add "abc" // 錯誤:必須指定接收者
          }
      }

      11.函數作用域

        在 Kotlin 中函數可以在文件頂層聲明,這意味著你不需要像一些語言如 Java、C# 或 Scala 那樣需要創 建一個類來保存一個函數。此外除了頂層函數,Kotlin 中函數也可以聲明在局部作用域、作為成員函數 以及擴展函數。

      12.局部函數

        Kotlin 支持局部函數,即一個函數在另一個函數內部:

      fun dfs(graph: Graph) {
          fun dfs(current: Vertex, visited: MutableSet<Vertex>) {
              if (!visited.add(current)) return 
              for (v in current.neighbors)
                  dfs(v, visited)
          }
          dfs(graph.vertices[0], HashSet())
      }

        局部函數可以訪問外部函數(即閉包)的局部變量,所以在上例中,visited 可以是局部變量:

      fun dfs(graph: Graph) {
          val visited = HashSet<Vertex>()
          fun dfs(current: Vertex) {
              if (!visited.add(current)) return
              for (v in current.neighbors)
                  dfs(v)
          }
          dfs(graph.vertices[0])
      }

      13.成員函數

        成員函數是在類或對象內部定義的函數:

      class Sample {
          fun foo() { print("Foo") }
      }

        成員函數以點表示法調用:

      Sample().foo() // 創建類 Sample 實例并調用 foo

      14.泛型函數

        函數可以有泛型參數,通過在函數名前使用尖括號指定:

      fun <T> singletonList(item: T): List<T> { /*......*/ }

      15.尾遞歸函數

        Kotlin支持一種稱為尾遞歸的函數式編程風格。這允許一些通常用循環寫的算法改用遞歸函數來寫,而無堆棧溢出的風險。當一個函數用tailrec修飾符標記并滿足所需的形式時,編譯器會優化該遞歸,留下一個快速而高效的基于循環的版本:

      val eps = 1E-10 // "good enough", could be 10^-15
      tailrec fun findFixPoint(x: Double = 1.0): Double
              = if (Math.abs(x - Math.cos(x)) < eps) x else findFixPoint(Math.cos(x))

        這段代碼計算余弦的不動點(fixpoint of cosine),這是一個數學常數。它只是重復地從 1.0 開始調用 Math.cos,直到結果不再改變,對于這里指定的 eps 精度會產生 0.7390851332151611 的結果。最終代碼相當于這種更傳統?格的代碼:

      val eps = 1E-10 // "good enough", could be 10^-15
      
      private fun findFixPoint(): Double {
          var x = 1.0
          while (true) {
              val y = Math.cos(x)
              if (Math.abs(x - y) < eps) return x 
              x = Math . cos (x)
          }
      }
      
      //要符合 tailrec 修飾符的條件的話,函數必須將其自身調用作為它執行的最后一個操作。
      //在遞歸調用后有更多代碼時,不能使用尾遞歸,并且不能用在try/catch/finally 塊中。
      //目前在 Kotlin for JVM 與 Kotlin/Native 中支持尾遞歸。

       

        

      posted @ 2020-06-30 17:05  王世楨  閱讀(735)  評論(0)    收藏  舉報
      主站蜘蛛池模板: a男人的天堂久久a毛片| 一区二区三区国产不卡| 丰满岳乱妇久久久| 手机在线国产精品| 最新中文字幕国产精品| 免费成人网一区二区天堂| 性夜黄a爽影免费看| 国产在线精品欧美日韩电影| 高颜值午夜福利在线观看| 国产麻豆精品久久一二三| 中文字幕久久国产精品| 亚洲人成亚洲人成在线观看| 在线免费播放av观看| 国产女同一区二区在线| 亚洲综合一区二区三区视频| 久久99久国产麻精品66| 久久精品熟女亚洲av艳妇| 亚洲av色夜色精品一区| 国产亚洲精久久久久久无码77777| 国产人妻高清国产拍精品| 新郑市| 四虎永久在线高清免费看| 东方四虎在线观看av| 欧洲免费一区二区三区视频| 亚洲精品中文字幕码专区| 亚洲亚洲人成综合网络| 国产一区二区午夜福利久久| 久久久久无码精品亚洲日韩| 日本道不卡一二三区视频| 无码国产偷倩在线播放老年人| 中文字幕日韩熟女av| 综合人妻久久一区二区精品| 亚洲精品乱码久久久久红杏| 四虎成人精品在永久免费| 国产精品中文字幕免费| 好男人好资源WWW社区| 国产不卡一区二区在线视频| 超清无码一区二区三区| 蜜桃一区二区三区在线看| 翘臀少妇被扒开屁股日出水爆乳| 亚洲av无码精品蜜桃|