KOTLIN開發語言文檔(官方文檔) -- 2.基本概念

来源:http://www.cnblogs.com/figozhg/archive/2016/01/18/5140832.html
-Advertisement-
Play Games

KOTLIN開發語言文檔(官方文檔)第二章、基本概念


網頁鏈接:https://kotlinlang.org/docs/reference/basic-types.html

2.   基本概念

2.1.  基本類型

從可以在任何變數處理調用成員函數和屬性角度來說,在Kotlin開發語言中,一切都是對象。有些類型是內嵌的,它們的實現進行過優化,用戶看到的仍是原始類。在這節中,我們說明大部分這些類型:數字,字元,布爾和數組。

2.1.1.   數字

Kotlin開發語言處理數組的方法類似Java開發語言,但是也有差別。例如,沒有隱含的數字擴寬的轉換,並且在相同的情況下,文字也有些不同。

Kotlin開發語言提供下列內嵌類型表示數字(這是類似Java開發語言):

類型

位寬度

Double

64

Float

32

Long

64

Int

32

Short

16

Byte

8

 

 

 

 

 

 

 

 

 

 

註意,在Kotlin開發語言中,字元不屬於數組。

2.1.1.1. 文字常數

對於整數值有下麵幾種文字常數:

—— 十進位數:123

—— 附加大寫字母L標準長整數:123L

—— 十六進位數:0x0F

—— 二進位數:0b00001011

註意:不支持八進位數字。

Kotlin開發語言還支持通用的浮點數表示法:

—— 預設是雙精度:123.5,123.5e10

—— 附加f或F表示單精度浮點數:123.5F

2.1.1.2. 表示法

在Java開發語言平臺上,數字是作為JVM基本類型進行物理存在的,除非需要一個可null數字引用(如:Int?)或包含在泛型。後一種情況下,是將數字裝箱的。

註意數字裝箱不保持一致性:

1 val a: Int = 10000
2 print(a === a) // 列印 'true'
3 val boxedA: Int? = a
4 val anotherBoxedA: Int? = a
5 print(boxedA === anotherBoxedA) // !!!列印 'false'!!!

而另一方面,卻保持相等:

1 val a: Int = 10000
2 print(a == a) // 列印 'true'
3 val boxedA: Int? = a
4 val anotherBoxedA: Int? = a
5 print(boxedA == anotherBoxedA) // 列印 'true'

2.1.1.3. 顯式轉換

由於不同的表示法,較小類型不是較大類型的子類型。如果是,就有下列麻煩了:

1 // 假設代碼,沒有實際編譯:
2 val a: Int? = 1 // 裝箱為Int (java.lang.Integer)
3 val b: Long? = a // 隱含轉換裝箱為Long (java.lang.Long)
4 print(a == b) // 令人驚訝! 當equals()檢查其它部分不是Long,就列印"false"

所以不僅僅是一致性,而且即使相當也會在此默默丟失一部分。

這樣,較小的類型不會隱含的轉換為較大的類型。這就是說,如果沒有進行明確的類型轉換,Byte類型值是不能賦值給Int類型變數。

1 val b: Byte = 1 // OK, 靜態文字檢查
2 val i: Int = b // 錯誤

可以進行明確(顯式)的數字寬度轉換:

1 val i: Int = b.toInt() // OK: 顯式寬度轉換

每項數字類型支持下列轉換:

toByte(): Byte

—toShort(): Short

—toInt(): Int

—toLong(): Long

—toFloat(): Float

—toDouble(): Double

—toChar(): Char

因為類型是從上下文推斷,以及適當的轉換重載了算術運算符,所以隱式轉換缺位是很少引人註目的,例如:

1 val l = 1L + 3 // Long + Int => Long

2.1.1.4. 運算

Kotlin開發語言支持對數字標準的一套運算,它們被聲明為相應類成員(但是,編譯器優化調用的相應指令)。查看:運算符重載(5.6)。

作為位運算,對於它們沒有特殊特性(字元),僅僅命名函數使其能以中綴方式被調用,如:

1 val x = (1 shl 2) and 0x000FF000

這是完整的位運算列表(僅僅對Int和Long類型有效):

— shl(bits) – signed shift left (Java’s <<)

— shr(bits) – signed shift right (Java’s >>)

— ushr(bits) – unsigned shift right (Java’s >>>)

— and(bits) – bitwise and

— or(bits) – bitwise or

— xor(bits) – bitwise xor

— inv() – bitwise inversion

2.1.2.   字元

char類型表示字元。它們不能直接作為數組處理:

1 fun check(c: Char) {
2   if (c == 1) { // ERROR: incompatible types
3     // ...
4   }
5 }

字元文字是在單引號中:’1’,’\n’,’\uFF00’。我們能夠明確地轉換字元到Int數字:

1 fun decimalDigitValue(c: Char): Int {
2   if (c !in '0'..'9')
3     throw IllegalArgumentException("Out of range")
4   return c.toInt() - '0'.toInt() // Explicit conversions to numbers
5 }

在需要可null引用時,像數字、字元是被裝箱。裝箱操作是不保證一致性的。

2.1.3.   布爾值

Boolean類型表示布爾值,它有兩個值:true和false。

如果需要可null引用時,布爾值可以被裝箱的。

布爾值的內置的運算包括:

— || – lazy分離 (註:這個“lazy”不知道怎樣翻譯好,就是 “或”為啥要這樣?)

— && – lazy連接

— ! – 非

2.1.4.   數組

在Kotlin開發語言中,Array類表示數組,它有get和set函數(即通過操作符重載約定轉成[]),有size屬性,以及其他一些有用的成員函數:

1 class Array<T> private constructor() {
2   val size: Int
3   fun get(index: Int): T
4   fun set(index: Int, value: T): Unit
5 
6   fun iterator(): Iterator<T>
7   // ...
8 }

可以用庫函數arrayOf(),將數組各項的數值傳遞給它,來創建一個數組,如:arrayOf(1,2,3)創建數組[1,2,3]。或者,用arrayOfNulls()庫函數創建一個指定尺寸(size)的數組,其元素均填充為null。

另一種選擇是用工廠函數獲得數組尺寸,並且返回指定索引位置的數組元素的初始值:

1 // Creates an Array<String> with values ["0", "1", "4", "9", "16"]
2 val asc = Array(5, { i -> (i * i).toString() })

如上所述,[]操作符表示調用成員函數get()和set()。

註意:與Java開發語言不同,在Kotlin開發語言中,數組是不變數。這意味著kotlin開發語言不允許賦值Array<String>到Array<Any>,這防止運行的可能的錯誤(但是,可以用Array<out Any>,查看:類型推測(3.7.2))。

Kotlin開發語言也有專用類表示原始類型的數組,不需要裝箱消耗:ByteArray、ShortArray、IntArray等等。這些類與Array類沒有繼承關係,但是它們有相同的一組方法和屬性。它們中的每一個都有相應的工廠函數:

1 val x: IntArray = intArrayOf(1, 2, 3)
2 x[0] = x[1] + x[2]

2.1.5.   串

String類型表示串。String是不可變的。串的元素是字元,可以用索引操作訪問:s[i]。可以用for迴圈遍歷一個串:

1 for (c in str) {
2   println(c)
3 }

2.1.5.1. 串文字

Kotlin開發語言有兩種串文字類型:包含轉義字元的轉義串和包含任意字元和新行符的原始串。轉義串非常像Java開發語言的串:

1 val s = "Hello, world!\n"

轉義可以用習慣的方法(用\)實現。

原始串由三引號(”””)定界的,包含非轉義字元、新行符,以及其它任意字元:

1 val text = """
2   for (c in "foo")
3     print(c)
4 """

2.1.5.2. 串模板

串可以包含模板表達式,即:可計算的代碼片段,其結果鏈接到串中。模板表達式以美元符號($)開始,和簡單的名字構成:

1 val i = 10
2 val s = "i = $i" // 計算結果是 "i = 10"

或是在大括弧中的任意表達式:

1 val s = "abc"
2 val str = "$s.length is ${s.length}" // 計算結果是 "abc.length is 3"

在原始串和轉義串中,都支持模板。如果需要表達$字元文字,則可以用下列語法:

1 val price = "${'$'}9.99"

2.2.  包

一個源文件可以是從聲明包開始的:

1 package foo.bar
2 
3 fun baz() {}
4 class Goo {}
5 // ...

源文件中的所有內容(如:類和函數)都包含在包的聲明中。所以,在上面例子中,baz()的完整名稱是foo.bar.baz,Goo的完整名稱是foo.bar.Goo。

如果源文件中沒有指明包,則這個文件中的內容屬於沒有名稱的“預設”包。

2.2.1.   導入(import)

除預設的import外,每個文件都可以有自己的import偽指令。Import的句法在語法(6.2)中描述了。

我們既可以導入單個名稱,如:

1 import foo.Bar // Bar is now accessible without qualification

也可以是範圍內所有可訪問的內容(包、類、對象等等):

1 import foo.* // everything in 'foo' becomes accessible

如果有命名衝突,可以在衝突項用as關鍵字重命名來消除:

1 import foo.Bar // Bar可以訪問
2 import bar.Bar as bBar // bBar 表示 'bar.Bar'

import關鍵字不限制導入的類;也可以用途導入其它聲明:

—— 頂層函數和屬性;

—— 在對象聲明(3.12.2)中聲明的函數和屬性;

—— 枚舉常數(3.11);

不像Java開發語言,Kotlin開發語言沒有獨立的“import static”句法;所有這些聲明都是用常規的import關鍵字來導入。

2.2.2.   頂層聲明的可視範圍

如果頂層聲明標註private,它是它所在文件的私有的(查看:可視性修飾符(3.4))

2.3.  控制流

2.3.1.   if表達式

在Kotlin開發語言中,if是一個表達式,即:它返回一個值。由於在此規則下普通if運行的很好,因此沒有三元運算符(?:else)。

 1 // 傳統用法
 2 var max = a 
 3 if (a < b) 
 4   max = b 
 5  
 6 // 帶else 
 7 var max: Int
 8 if (a > b) 
 9   max = a 
10 else 
11   max = b 
12  
13 // 作為表達式
14 val max = if (a > b) a else b

if分支可以是代碼塊,最後表達式是代碼塊的值:

1 val max = if (a > b) { 
2     print("Choose a") 
3     a 
4   } 
5   else { 
6     print("Choose b") 
7     b 
8   }

如果用if作為表達式,而不是語句(例如,返回它的值,或賦值給變數),表達式要求有else分支。

查看:if語法(6.2.3.4)

2.3.2.   when表達式

When替代了類似C開發語言的switch操作符。最簡單形式如此:

1 when (x) {
2   1 -> print("x == 1")
3   2 -> print("x == 2")
4   else -> { // Note the block
5     print("x is neither 1 nor 2")
6   }
7 }

when將變數與其的所有分支順序逐一匹配,直至找到條件相符的分支。when即可用作表達式,也可以用作語句,滿足條件的分支值就是整個表達式的值。如果它用作語句,個別分支的值將被忽略。(就如同if,每個分支可以是一個代碼塊,代碼塊中最後的表達式值就是其值。)

else分支等價與沒有其它分支滿足條件。如果when用作一個表達式,且編譯器無法驗證分支條件覆蓋了所有的可能情況,則強制性要求else分支。

如果多種情況都有相同的處理方法,也可以用逗號將分支條件組合起來:

1 when (x) {
2   0, 1 -> print("x == 0 or x == 1")
3   else -> print("otherwise")
4 }

可以用任意表達式(不僅僅是常數)作為分支條件:

1 when (x) {
2   parseInt(s) -> print("s encodes x")
3   else -> print("s does not encode x")
4 }

還可以用in或!in檢查一個範圍(5.2)或集合:

1 when (x) {
2   in 1..10 -> print("x is in the range")
3   in validNumbers -> print("x is valid")
4   !in 10..20 -> print("x is outside the range")
5   else -> print("none of the above")
6 }

另一種情況,可以用is或!is檢查特別類型。註意,由於智能轉換(5.4),不需要任何額外的檢查就可以訪問類型的方法和屬性:

1 val hasPrefix = when(x) {
2   is String -> x.startsWith("prefix")
3   else -> false
4 }

when還可以用來替換if-else鏈。如果沒有變數,分支條件就是簡單的布爾表達式,且在when條件為true時,執行該分支:

1 when {
2   x.isOdd() -> print("x is odd")
3   x.isEven() -> print("x is even")
4   else -> print("x is funny")
5 }

查看:when語法(6.2.3.4.2.1)。

2.3.3.   for迴圈

for迴圈遍歷提供的任何一個迭代器。句法如下:

1 for (item in collection)
2   print(item)

迴圈體可以是一個代碼塊。

1 for (item: Int in ints) {
2   // ...
3 }

如前所述,for迴圈遍歷提供的任何一個迭代器,即:

—— 有成員iterator()或擴展函數iterator(),它返回類型:

 —— 有成員next()或擴展函數next(),和

 —— 有返回布爾類型的成員hasNext()或擴展函數hasNext()。

所有這三個函數是需要作為操作符的。

如果要利用索引遍歷一個數組或列表,可以這樣做:

1 for (i in array.indices)
2   print(array[i])

註意,這句“遍歷一個範圍”是由編譯器優化實現的,不需要產生額外的對象。

或者,可以用withIndex庫函數:

1 for ((index, value) in array.withIndex()) {
2     println("the element at $index is $value")
3 }

查看:for語法(6.2.3.3)。

2.3.4.   while迴圈

while和do…while都是如常規一樣工作:

1 while (x > 0) {
2   x--
3 }
4 
5 do {
6   val y = retrieveData()
7 } while (y != null) // y is visible here!

查看:while語法(6.2.3.3)。

2.3.5.   迴圈的中斷和繼續

Kotlin開發語言支持迴圈中的傳統break和continue操作符。查看:返回和跳轉(2.4)。

2.4.  返回和跳轉

Kotlin開發語言有三種結構化的跳轉操作符:

—— return。預設情況下,由最近的函數返回,或匿名函數的返回。

—— break。終止最近一層迴圈。

—— continue。繼續最近一層迴圈的下一步。

2.4.1.   中斷和繼續標簽

在Kotlin開發語言中,任何表達式都可以帶標簽。標簽的格式是在標識符後跟@來表示,如:abc@,fooBar@都是合法的標簽(查看:語法(6.2))。為了標記表達式,只需要在其前面加上標簽即可:

1 loop@ for (i in 1..100) {
2   // ...
3 }

現在,就可以break或continue到標簽了:

1 loop@ for (i in 1..100) {
2   for (j in 1..100) {
3     if (...)
4       break@loop
5   }
6 }

帶有標簽的break跳轉到標記loop之後的執行點。Continue繼續進行標記loop的下一步。

2.4.2.   在標簽處返回

Kotlin開發語言在函數體、局部函數和對象表達式中,允許函數嵌套。Return允許我們有外部函數返回。最重要的用例是由Lambda表達式返回。我們這樣編寫回調:

1 fun foo() {
2   ints.forEach {
3     if (it == 0) return
4     print(it)
5   }
6 }

返回表達式是由最近函數返回,即:foo。(註意:這樣對Lambda表達式僅支持非局部返回到內嵌函數(4.1.5)。)如果要從Lambda表達式返回,就需要標記它限制返回:

1 fun foo() {
2   ints.forEach lit@ {
3     if (it == 0) return@lit
4     print(it)
5   }
6 }

現在,就僅從Lambda表達式返回。通常,最方便的是用隱含標簽:這樣標簽與傳遞給Lambda表達式的函數同名。

1 fun foo() {
2   ints.forEach {
3     if (it == 0) return@forEach
4     print(it)
5   }
6 }

或者,可以用匿名函數(4.2.3.3)替代Lambda表達式。在匿名函數中的return語句是從匿名函數自身返回。

1 fun foo() {
2   ints.forEach(fun(value: Int) {
3     if (value == 0) return
4     print(value)
5   })
6 }

當返回一個值是,解析器優先給出恰當的返回,如:

1 return@a 1

就是“在標簽@a處返回1”而不是“返回標簽表達式(@a 1)”。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • javascript如何將字元串轉換成數組:數組和字元串的相互轉換是比較常見的操作,關於數組如何轉換成字元串可以參與js將數組轉換為字元串一章節,這裡就不介紹了,下麵將通過代碼實例介紹一下如何將字元串轉換為數組。代碼實例如下:var arr=[1,2,4,5,6,2,4];var str=arr.s...
  • css如何實現未知寬高div中圖片垂直水平居中效果:在有時候可能有這樣的情況,那就是想讓一個圖片在div中實現垂直水平居中效果,但是有時候div的尺寸是位置的,下麵通過代碼實例介紹一下在這種情況下如何實現圖片的垂直水平居中效果。代碼如下:實例一:螞蟻部落上面你的代碼可以讓圖片垂直水平居中,當然這裡,...
  • 點擊回車實現按鈕點擊功能:在實際應用中,可能有這樣的需求,點擊一個按鈕可以執行一個功能,當點擊回車的時候也可以實現此功能,也就是說點擊回車的時候也觸發的點擊事件,下麵就通過代碼實例介紹一下如何實現此功能。代碼如下:螞蟻部落 以上代碼實現了我們的要求,點擊按鈕或者點擊回車都可以將div的背景色設置為藍...
  • js將數組轉換為字元串:有時候將數組元素轉換成一個字元串更容易操作,下麵就通過代碼實例介紹一下如何實現此效果。代碼實例如下:var arr=[1,2,4,5,6,2,4];console.log(arr.join(""));使用Array自帶的join()函數即可實現此效果。關於join()函數可以...
  • 利用div和css製作三角形效果:本章節介紹一下如何利用div和css實現三角形效果,雖然看起來表神奇,但是原理是非常的簡單。代碼如下:螞蟻部落其實這個三角形是利用div的邊框"擠出"來的,邊框由於採用了不同的顏色,所以很好區分,如果只保留一個方位的三角形,可以自行設置邊框顏色或者刪除邊框就可以了。...
  • UITabBarController是開發中經常會用到的一個視圖控制器,但是預設的UITabBarController經常不能夠完全滿足我們的需求,所以我們經常需要自定義一個UITabBarController。 接下來,我們就來自定義一個UITabBarController。首先我們應該明白...
  • 線程通信、ActivityThread及Thread類是理解Android線程管理的關鍵。 線程,作為CPU調度資源的基本單位,在Android等針對嵌入式設備的操作系統中,有著非常重要和基礎的作用。本小節主要從以下三個方面進行分析: 《Android線程管理(一)——線程通信》 《Android線...
  • 一,效果圖。二,工程圖。三,代碼。RootViewController.h#import //加入頭文件#import "DCPathButton.h"@interface RootViewController : [email protected]#i...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...