<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Kotlin 1.1 的新特性 ## 目錄 [TOC] ## JavaScrip 從 Kotlin 1.1 開始,JavaScript 目標平臺不再當是實驗性的。所有語言功能都支持,并且有許多新的工具用于與前端開發環境集成。更詳細改動列表,請參見下文。 ## 協程(實驗性的) Kotlin 1.1 的關鍵新特性是*協程*,它帶來了 `future`/`await`、 `yield` 以及類似的編程模式的支持。Kotlin 的設計中的關鍵特性是協程執行的實現是語言庫的一部分,而不是語言的一部分,所以你不必綁定任何特定的編程范式或并發庫。 協程實際上是一個輕量級的線程,可以掛起并稍后恢復。協程通過[*掛起函數*](http://www.hmoore.net/alex_wsc/android_kotlin/1318237)支持:對這樣的函數的調用可能會掛起協程,并啟動一個新的協程,我們通常使用匿名掛起函數(即掛起 lambda 表達式)。 我們來看看在外部庫 [kotlinx.coroutines](https://github.com/kotlin/kotlinx.coroutines) 中實現的 `async`/`await`: ```kotlin // 在后臺線程池中運行該代碼 fun asyncOverlay() = async(CommonPool) { // 啟動兩個異步操作 val original = asyncLoadImage("original") val overlay = asyncLoadImage("overlay") // 然后應用疊加到兩個結果 applyOverlay(original.await(), overlay.await()) } // 在 UI 上下文中啟動新的協程 launch(UI) { // 等待異步疊加完成 val image = asyncOverlay().await() // 然后在 UI 中顯示 showImage(image) } ``` 這里,`async { …… }` 啟動一個協程,當我們使用 `await()` 時,掛起協程的執行,而執行正在等待的操作,并且在等待的操作完成時恢復(可能在不同的線程上) 。 標準庫通過 `yield` 和 `yieldAll` 函數使用協程來支持*惰性生成序列*。在這樣的序列中,在取回每個元素之后掛起返回序列元素的代碼塊,并在請求下一個元素時恢復。這里有一個例子: ```kotlin import kotlin.coroutines.experimental.* fun main(args: Array<String>) { //sampleStart val seq = buildSequence { for (i in 1..5) { // 產生一個 i 的平方 yield(i * i) } // 產生一個區間 yieldAll(26..28) } // 輸出該序列 println(seq.toList()) //sampleEnd } ``` 運行上面的代碼以查看結果。隨意編輯它并再次運行! 更多信息請參見[協程文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318237)及[教程](https://www.kotlincn.net/docs/tutorials/coroutines/coroutines-basic-jvm.html)。 請注意,協程目前還是一個**實驗性的特性**,這意味著 Kotlin 團隊不承諾在最終的 1.1 版本時保持該功能的向后兼容性。 ## 其他語言功能 ### 類型別名 類型別名允許你為現有類型定義備用名稱。這對于泛型類型(如集合)以及函數類型最有用。 這里有幾個例子 ```kotlin //sampleStart typealias OscarWinners = Map<String, String> fun countLaLaLand(oscarWinners: OscarWinners) = oscarWinners.count { it.value.contains("La La Land") } // 請注意,類型名稱(初始名和類型別名)是可互換的: fun checkLaLaLandIsTheBestMovie(oscarWinners: Map<String, String>) = oscarWinners["Best picture"] == "La La Land" //sampleEnd fun oscarWinners(): OscarWinners { return mapOf( "Best song" to "City of Stars (La La Land)", "Best actress" to "Emma Stone (La La Land)", "Best picture" to "Moonlight" /* …… */) } fun main(args: Array<String>) { val oscarWinners = oscarWinners() val laLaLandAwards = countLaLaLand(oscarWinners) println("LaLaLandAwards = $laLaLandAwards (in our small example), but actually it's 6.") val laLaLandIsTheBestMovie = checkLaLaLandIsTheBestMovie(oscarWinners) println("LaLaLandIsTheBestMovie = $laLaLandIsTheBestMovie") } ``` 更詳細信息請參閱其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/type-aliases.md)。 ### 已綁定的可調用引用 現在可以使用 `::` 操作符來獲取指向特定對象實例的方法或屬性的[成員引用](http://www.hmoore.net/alex_wsc/android_kotlin/1318347)。以前這只能用 lambda 表達式表示。 這里有一個例子: ```kotlin //sampleStart val numberRegex = "\\d+".toRegex() val numbers = listOf("abc", "123", "456").filter(numberRegex::matches) //sampleEnd fun main(args: Array<String>) { println("Result is $numbers") } ``` 更詳細信息請參閱其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/bound-callable-references.md)。 ### 密封類和數據類 Kotlin 1.1 刪除了一些對 Kotlin 1.0 中已存在的密封類和數據類的限制。現在你可以在同一個文件中的任何地方定義一個密封類的子類,而不只是以作為密封類嵌套類的方式。數據類現在可以擴展其他類。這可以用來友好且清晰地定義一個表達式類的層次結構: ```kotlin //sampleStart sealed class Expr data class Const(val number: Double) : Expr() data class Sum(val e1: Expr, val e2: Expr) : Expr() object NotANumber : Expr() fun eval(expr: Expr): Double = when (expr) { is Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN } val e = eval(Sum(Const(1.0), Const(2.0))) //sampleEnd fun main(args: Array<String>) { println("e is $e") // 3.0 } ``` 更詳細信息請參閱其[文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318307)或者[密封類](https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)及[數據類](https://github.com/Kotlin/KEEP/blob/master/proposals/data-class-inheritance.md)的 KEEP。 ### lambda 表達式中的解構 現在可以使用[解構聲明](http://www.hmoore.net/alex_wsc/android_kotlin/1318339)語法來解開傳遞給 lambda 表達式的參數。 這里有一個例子: ```kotlin fun main(args: Array<String>) { //sampleStart val map = mapOf(1 to "one", 2 to "two") // 之前 println(map.mapValues { entry -> val (key, value) = entry "$key -> $value!" }) // 現在 println(map.mapValues { (key, value) -> "$key -> $value!" }) //sampleEnd } ``` 更詳細信息請參閱其[文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318339)及其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/destructuring-in-parameters.md)。 ### 下劃線用于未使用的參數 對于具有多個參數的 lambda 表達式,可以使用 `_` 字符替換不使用的參數的名稱: ```kotlin fun main(args: Array<String>) { val map = mapOf(1 to "one", 2 to "two") //sampleStart map.forEach { _, value -> println("$value!") } //sampleEnd } ``` 這也適用于[解構聲明](http://www.hmoore.net/alex_wsc/android_kotlin/1318339): ```kotlin data class Result(val value: Any, val status: String) fun getResult() = Result(42, "ok").also { println("getResult() returns $it") } fun main(args: Array<String>) { //sampleStart val (_, status) = getResult() //sampleEnd println("status is '$status'") } ``` 更詳細信息請參閱其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/underscore-for-unused-parameters.md)。 ### 數字字面值中的下劃線 正如在 Java 8 中一樣,Kotlin 現在允許在數字字面值中使用下劃線來分隔數字分組: ```kotlin //sampleStart val oneMillion = 1_000_000 val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010 //sampleEnd fun main(args: Array<String>) { println(oneMillion) println(hexBytes.toString(16)) println(bytes.toString(2)) } ``` 更詳細信息請參閱其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/underscores-in-numeric-literals.md)。 ### 對于屬性的更短語法 對于沒有自定義訪問器、或者將 getter 定義為表達式主體的屬性,現在可以省略屬性的類型: ```kotlin //sampleStart data class Person(val name: String, val age: Int) { val isAdult get() = age >= 20 // 屬性類型推斷為 “Boolean” } //sampleEnd fun main(args: Array<String>) { val akari = Person("Akari", 26) println("$akari.isAdult = ${akari.isAdult}") } ``` ### 內聯屬性訪問器 如果屬性沒有幕后字段,現在可以使用 `inline` 修飾符來標記該屬性訪問器。這些訪問器的編譯方式與[內聯函數](http://www.hmoore.net/alex_wsc/android_kotlin/1318318)相同。 ```kotlin //sampleStart public val <T> List<T>.lastIndex: Int inline get() = this.size - 1 //sampleEnd fun main(args: Array<String>) { val list = listOf('a', 'b') // 其 getter 會內聯 println("Last index of $list is ${list.lastIndex}") } ``` 你也可以將整個屬性標記為 `inline`——這樣修飾符應用于兩個訪問器。更詳細信息請參閱其[文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318318)及其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/inline-properties.md)。 ### 局部委托屬性 現在可以對局部變量使用[委托屬性](http://www.hmoore.net/alex_wsc/android_kotlin/1318315)語法。一個可能的用途是定義一個延遲求值的局部變量: ```kotlin import java.util.Random fun needAnswer() = Random().nextBoolean() fun main(args: Array<String>) { //sampleStart val answer by lazy { println("Calculating the answer...") 42 } if (needAnswer()) { // 返回隨機值 println("The answer is $answer.") // 此時計算出答案 } else { println("Sometimes no answer is the answer...") } //sampleEnd } ``` 更詳細信息請參閱其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/local-delegated-properties.md)。 ### 委托屬性綁定的攔截 對于[委托屬性](http://www.hmoore.net/alex_wsc/android_kotlin/1318315),現在可以使用 `provideDelegate` 操作符攔截委托到屬性之間的綁定。 例如,如果我們想要在綁定之前檢測屬性名稱,我們可以這樣寫: ```kotlin class ResourceLoader<T>(id: ResourceID<T>) { operator fun provideDelegate(thisRef: MyUI, property: KProperty<*>): ReadOnlyProperty<MyUI, T> { checkProperty(thisRef, property.name) …… // 屬性創建 } private fun checkProperty(thisRef: MyUI, name: String) { …… } } fun <T> bindResource(id: ResourceID<T>): ResourceLoader<T> { …… } class MyUI { val image by bindResource(ResourceID.image_id) val text by bindResource(ResourceID.text_id) } ``` `provideDelegate` 方法在創建 `MyUI` 實例期間將會為每個屬性調用,并且可以立即執行必要的驗證。 更詳細信息請參閱其[文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318315)。 ### 泛型枚舉值訪問 現在可以用泛型的方式來對枚舉類的值進行枚舉: ```kotlin //sampleStart enum class RGB { RED, GREEN, BLUE } inline fun <reified T : Enum<T>> printAllValues() { print(enumValues<T>().joinToString { it.name }) } //sampleEnd fun main(args: Array<String>) { printAllValues<RGB>() // 輸出 RED, GREEN, BLUE } ``` ### 對于 DSL 中隱式接收者的作用域控制 `@DslMarker` 注解允許限制來自 DSL 上下文中的外部作用域的接收者的使用。考慮那個典型的 [HTML 構建器示例](type-safe-builders.html): ```kotlin table { tr { td { + "Text" } } } ``` 在 Kotlin 1.0 中,傳遞給 `td` 的 lambda 表達式中的代碼可以訪問三個隱式接收者:傳遞給 `table`、`tr`和 `td` 的。 這允許你調用在上下文中沒有意義的方法——例如在 `td` 里面調用 `tr`,從而在 `<td>` 中放置一個 `<tr>` 標簽。 在 Kotlin 1.1 中,你可以限制這種情況,以使只有在 `td` 的隱式接收者上定義的方法會在傳給 `td` 的 lambda 表達式中可用。你可以通過定義標記有 `@DslMarker` 元注解的注解并將其應用于標記類的基類。 更詳細信息請參閱其[文檔](http://www.hmoore.net/alex_wsc/android_kotlin/1318349)及其 [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/scope-control-for-implicit-receivers.md)。 ### `rem` 操作符 `mod` 操作符現已棄用,而使用 `rem` 取代。動機參見[這個問題](https://youtrack.jetbrains.com/issue/KT-14650)。 ## 標準庫 ### 字符串到數字的轉換 在 String 類中有一些新的擴展,用來將它轉換為數字,而不會在無效數字上拋出異常: `String.toIntOrNull(): Int?`、 `String.toDoubleOrNull(): Double?` 等。 ```kotlin val port = System.getenv("PORT")?.toIntOrNull() ?: 80 ``` 還有整數轉換函數,如 `Int.toString()`、 `String.toInt()`、 `String.toIntOrNull()`,每個都有一個帶有 `radix` 參數的重載,它允許指定轉換的基數(2 到 36)。 ### onEach() `onEach` 是一個小、但對于集合和序列很有用的擴展函數,它允許對操作鏈中的集合/序列的每個元素執行一些操作,可能帶有副作用。 對于迭代其行為像 `forEach` 但是也進一步返回可迭代實例。 對于序列它返回一個包裝序列,它在元素迭代時延遲應用給定的動作。 ```kotlin inputDir.walk() .filter { it.isFile && it.name.endsWith(".txt") } .onEach { println("Moving $it to $outputDir") } .forEach { moveFile(it, File(outputDir, it.toRelativeString(inputDir))) } ``` ### also()、takeIf() 和 takeUnless() 這些是適用于任何接收者的三個通用擴展函數。 `also` 就像 `apply`:它接受接收者、做一些動作、并返回該接收者。二者區別是在 `apply` 內部的代碼塊中接收者是 `this`,而在 `also` 內部的代碼塊中是 `it`(并且如果你想的話,你可以給它另一個名字)。當你不想掩蓋來自外部作用域的 `this` 時這很方便: ```kotlin class Block { lateinit var content: String } //sampleStart fun Block.copy() = Block().also { it.content = this.content } //sampleEnd // 使用“apply”代替 fun Block.copy1() = Block().apply { this.content = this@copy1.content } fun main(args: Array<String>) { val block = Block().apply { content = "content" } val copy = block.copy() println("Testing the content was copied:") println(block.content == copy.content) } ``` `takeIf` 就像單個值的 `filter`。它檢測接收者是否滿足該謂詞,并在滿足時返回該接收者否則不滿足時返回 `null`。 結合 elvis-操作符和及早返回,它允許編寫如下結構: ```kotlin val outDirFile = File(outputDir.path).takeIf { it.exists() } ?: return false // 對現有的 outDirFile 做些事情 ``` ```kotlin fun main(args: Array<String>) { val input = "Kotlin" val keyword = "in" //sampleStart val index = input.indexOf(keyword).takeIf { it >= 0 } ?: error("keyword not found") // 對輸入字符串中的關鍵字索引做些事情,鑒于它已找到 //sampleEnd println("'$keyword' was found in '$input'") println(input) println(" ".repeat(index) + "^") } ``` `takeUnless` 與 `takeIf` 相同,只是它采用了反向謂詞。當它 _不_ 滿足謂詞時返回接收者,否則返回 `null`。因此,上面的示例之一可以用 `takeUnless` 重寫如下: ```kotlin val index = input.indexOf(keyword).takeUnless { it < 0 } ?: error("keyword not found") ``` 當你有一個可調用的引用而不是 lambda 時,使用也很方便: ```kotlin private fun testTakeUnless(string: String) { //sampleStart val result = string.takeUnless(String::isEmpty) //sampleEnd println("string = \"$string\"; result = \"$result\"") } fun main(args: Array<String>) { testTakeUnless("") testTakeUnless("abc") } ``` ### groupingBy() 此 API 可以用于按照鍵對集合進行分組,并同時折疊每個組。 例如,它可以用于計算文本中字符的頻率: ```kotlin fun main(args: Array<String>) { val words = "one two three four five six seven eight nine ten".split(' ') //sampleStart val frequencies = words.groupingBy { it.first() }.eachCount() //sampleEnd println("Counting first letters: $frequencies.") // 另一種方式是使用“groupBy”和“mapValues”創建一個中間的映射, // 而“groupingBy”的方式會即時計數。 val groupBy = words.groupBy { it.first() }.mapValues { (_, list) -> list.size } println("Comparing the result with using 'groupBy': ${groupBy == frequencies}.") } ``` ### Map.toMap() 和 Map.toMutableMap() 這倆函數可以用來簡易復制映射: ```kotlin class ImmutablePropertyBag(map: Map<String, Any>) { private val mapCopy = map.toMap() } ``` ### Map.minus(key) 運算符 `plus` 提供了一種將鍵值對添加到只讀映射中以生成新映射的方法,但是沒有一種簡單的方法來做相反的操作:從映射中刪除一個鍵采用不那么直接的方式如 `Map.filter()` 或 `Map.filterKeys()`。 現在運算符 `minus` 填補了這個空白。有 4 個可用的重載:用于刪除單個鍵、鍵的集合、鍵的序列和鍵的數組。 ```kotlin fun main(args: Array<String>) { //sampleStart val map = mapOf("key" to 42) val emptyMap = map - "key" //sampleEnd println("map: $map") println("emptyMap: $emptyMap") } ``` ### minOf() 和 maxOf() 這些函數可用于查找兩個或三個給定值中的最小和最大值,其中值是原生數字或 `Comparable` 對象。每個函數還有一個重載,它接受一個額外的 `Comparator` 實例,如果你想比較自身不可比的對象的話。 ```kotlin fun main(args: Array<String>) { //sampleStart val list1 = listOf("a", "b") val list2 = listOf("x", "y", "z") val minSize = minOf(list1.size, list2.size) val longestList = maxOf(list1, list2, compareBy { it.size }) //sampleEnd println("minSize = $minSize") println("longestList = $longestList") } ``` ### 類似數組的列表實例化函數 類似于 `Array` 構造函數,現在有創建 `List` 和 `MutableList` 實例的函數,并通過調用 lambda 表達式來初始化每個元素: ```kotlin fun main(args: Array<String>) { //sampleStart val squares = List(10) { index -> index * index } val mutable = MutableList(10) { 0 } //sampleEnd println("squares: $squares") println("mutable: $mutable") } ``` ### Map.getValue() `Map` 上的這個擴展函數返回一個與給定鍵相對應的現有值,或者拋出一個異常,提示找不到該鍵。如果該映射是用 `withDefault` 生成的,這個函數將返回默認值,而不是拋異常。 ```kotlin fun main(args: Array<String>) { //sampleStart val map = mapOf("key" to 42) // 返回不可空 Int 值 42 val value: Int = map.getValue("key") val mapWithDefault = map.withDefault { k -> k.length } // 返回 4 val value2 = mapWithDefault.getValue("key2") // map.getValue("anotherKey") // <- 這將拋出 NoSuchElementException //sampleEnd println("value is $value") println("value2 is $value2") } ``` ### 抽象集合 這些抽象類可以在實現 Kotlin 集合類時用作基類。對于實現只讀集合,有 `AbstractCollection`、 `AbstractList`、 `AbstractSet` 和 `AbstractMap`,而對于可變集合,有 `AbstractMutableCollection`、 `AbstractMutableList`、 `AbstractMutableSet` 和 `AbstractMutableMap`。在 JVM 上,這些抽象可變集合從 JDK 的抽象集合繼承了大部分的功能。 ### 數組處理函數 標準庫現在提供了一組用于逐個元素操作數組的函數:比較(`contentEquals` 和 `contentDeepEquals`),哈希碼計算(`contentHashCode` 和 `contentDeepHashCode`),以及轉換成一個字符串(`contentToString` 和`contentDeepToString`)。它們都支持 JVM(它們作為 `java.util.Arrays` 中的相應函數的別名)和 JS(在Kotlin 標準庫中提供實現)。 ```kotlin fun main(args: Array<String>) { //sampleStart val array = arrayOf("a", "b", "c") println(array.toString()) // JVM 實現:類型及哈希亂碼 println(array.contentToString()) // 良好格式化為列表 //sampleEnd } ``` ## JVM 后端 ### Java 8 字節碼支持 Kotlin 現在可以選擇生成 Java 8 字節碼(命令行選項 `-jvm-target 1.8` 或者 Ant/Maven/Gradle 中的相應選項)。目前這并不改變字節碼的語義(特別是,接口和 lambda 表達式中的默認方法的生成與 Kotlin 1.0 中完全一樣),但我們計劃在以后進一步使用它。 ### Java 8 標準庫支持 現在有支持在 Java 7 和 8 中新添加的 JDK API 的標準庫的獨立版本。如果你需要訪問新的 API,請使用 `kotlin-stdlib-jre7` 和 `kotlin-stdlib-jre8` maven 構件,而不是標準的 `kotlin-stdlib`。這些構件是在 `kotlin-stdlib` 之上的微小擴展,它們將它作為傳遞依賴項帶到項目中。 ### 字節碼中的參數名 Kotlin 現在支持在字節碼中存儲參數名。這可以使用命令行選項 `-java-parameters` 啟用。 ### 常量內聯 編譯器現在將 `const val` 屬性的值內聯到使用它們的位置。 ### 可變閉包變量 用于在 lambda 表達式中捕獲可變閉包變量的裝箱類不再具有 volatile 字段。此更改提高了性能,但在一些罕見的使用情況下可能導致新的競爭條件。如果受此影響,你需要提供自己的同步機制來訪問變量。 ### javax.scripting 支持 Kotlin 現在與[javax.script API](https://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html)(JSR-223)集成。 其 API 允許在運行時求值代碼段: ```kotlin val engine = ScriptEngineManager().getEngineByExtension("kts")!! engine.eval("val x = 3") println(engine.eval("x + 2")) // 輸出 5 ``` 關于使用 API 的示例項目參見[這里](https://github.com/JetBrains/kotlin/tree/master/libraries/examples/kotlin-jsr223-local-example)。 ### kotlin.reflect.full [為 Java 9 支持準備](https://blog.jetbrains.com/kotlin/2017/01/kotlin-1-1-whats-coming-in-the-standard-library/),在 `kotlin-reflect.jar` 庫中的擴展函數和屬性已移動到 `kotlin.reflect.full` 包中。舊包(`kotlin.reflect`)中的名稱已棄用,將在Kotlin 1.2 中刪除。請注意,核心反射接口(如 `KClass`)是 Kotlin 標準庫(而不是 `kotlin-reflect`)的一部分,不受移動影響。 ## JavaScript 后端 ### 統一的標準庫 Kotlin 標準庫的大部分目前可以從代碼編譯成 JavaScript 來使用。 特別是,關鍵類如集合(`ArrayList`、 `HashMap` 等)、異常(`IllegalArgumentException` 等)以及其他幾個關鍵類(`StringBuilder`、 `Comparator`)現在都定義在 `kotlin` 包下。在 JVM 平臺上,一些名稱是相應 JDK 類的類型別名,而在 JS 平臺上,這些類在 Kotlin 標準庫中實現。 ### 更好的代碼生成 JavaScript 后端現在生成更加可靜態檢測的代碼,這對 JS 代碼處理工具(如minifiers、 optimisers、 linters 等)更加友好。 ### `external` 修飾符 如果你需要以類型安全的方式在 Kotlin 中訪問 JavaScript 實現的類,你可以使用 `external` 修飾符寫一個 Kotlin 聲明。(在 Kotlin 1.0 中,使用了 `@native` 注解。)與 JVM 目標平臺不同,JS 平臺允許對類和屬性使用 external 修飾符。例如,可以按以下方式聲明 DOM `Node` 類: ```kotlin external class Node { val firstChild: Node fun appendChild(child: Node): Node fun removeChild(child: Node): Node // 等等 } ``` ### 改進的導入處理 現在可以更精確地描述應該從 JavaScript 模塊導入的聲明。 如果在外部聲明上添加 `@JsModule("<模塊名>")` 注解,它會在編譯期間正確導入到模塊系統(CommonJS或AMD)。例如,使用 CommonJS,該聲明會通過 `require(……)` 函數導入。 此外,如果要將聲明作為模塊或全局 JavaScript 對象導入,可以使用 `@JsNonModule` 注解。 例如,以下是將 JQuery 導入 Kotlin 模塊的方法: ```kotlin external interface JQuery { fun toggle(duration: Int = definedExternally): JQuery fun click(handler: (Event) -> Unit): JQuery } @JsModule("jquery") @JsNonModule @JsName("$") external fun jquery(selector: String): JQuery ``` 在這種情況下,JQuery 將作為名為 `jquery` 的模塊導入。或者,它可以用作 $-對象,這取決于Kotlin編譯器配置使用哪個模塊系統。 你可以在應用程序中使用如下所示的這些聲明: ```kotlin fun main(args: Array<String>) { jquery(".toggle-button").click { jquery(".toggle-panel").toggle(300) } } ```
                  <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>

                              哎呀哎呀视频在线观看