基本數(shù)據(jù)類型Int,Boolean及其他
在Java里面把基本數(shù)據(jù)類型和引用類型做了區(qū)分,例如int 和 Integer 這兩個類型. 在Kotlin中不區(qū)分基本數(shù)據(jù)類型和包裝類型,永遠(yuǎn)都是同一個類型(比如:Int)
val i : Int = 1
val list : List<Int> = listof(1,2,3)
不過表面上Kotlin不去區(qū)分基本數(shù)據(jù)類型和包裝類型,但在編譯時逢防,kotlin是有基本數(shù)據(jù)類型和包裝類型的區(qū)分的良哲,因為用引用類型去代替基本數(shù)據(jù)類型效率是很低图贸,所以koltin對于變量枉圃,屬性,參數(shù)和返回類型都會編譯成基本數(shù)據(jù)類型陨簇,唯一不可行的是泛型.
另外一點是當(dāng)你在Kotlin中使用Java聲明時,java基本數(shù)據(jù)類型會變成非空類型(而不是平臺類型),因為它們不能持有null值.
可空的基本數(shù)據(jù)類型: Int?,Boolean?及其他
kotlin中可空類型不能用Java基本類型表示迹淌,因為null只能被存儲在java的引用類型變量中河绽。這意味著任何時候只要使用了基本數(shù)據(jù)類型的可空版本,就會編譯成對應(yīng)的包裝類型.
下面來看一個小案例用來展示Int?的使用
data class Person(val name: String, val age: Int ?= null){
fun isOlderThan(other: Person) : Boolean?{
if(age == null || other.age == null)
return null
return age > other.age
}
}
>>>println(Person(“Sam”, 35).isOlderThan(Person(“Amy”,42)))
false
>>>println(Person(“Sam”, 35).isOlderThan(Person(“Jane”)))
null
這里必須檢查兩個Person的age是否都不為null. 另外如果你用基本數(shù)據(jù)類型作為泛型類的類型參數(shù)唉窃,那么Kotlin會使用該類型的包裝形式. 例如下面會創(chuàng)建一個Interger包裝類的列表耙饰,盡管你重來沒有指定過可空類型或者用過null值:
val listofInts = listof(1,2,3)
數(shù)字轉(zhuǎn)換
kotlin不會自動的對數(shù)字類型進行轉(zhuǎn)換, 如下
val i = 1
val l : Long = i
相反,必須顯示地進行轉(zhuǎn)換:
val i = 1
val l : Long = I.toLong()
每一種基本數(shù)據(jù)類型(Boolean除外)都定義有轉(zhuǎn)換函數(shù): toByte(), toShort(), toChar()等纹份。這些函數(shù)支持雙向轉(zhuǎn)換: 既可以把小范圍的類型擴展到大范圍, 比如Int.toLong(), 也可以把大范圍類型截取到小范圍, 比如Long.toInt().
為了避免意外情況苟跪,Kotlin要求轉(zhuǎn)換必須是顯示的,尤其是在比較裝箱值的時候蔓涧。比較兩個裝箱值equals方法不僅會檢查它們存儲的值件已,還要比較裝箱類型。所以在Java中new Integer(42).equals(new Long(42))會返回false. 假設(shè)Kotlin支持隱式轉(zhuǎn)換元暴,你也許會這樣寫
val x = 1
val list = listOf(1L,2L,3L)
x in list
Kotlin要求顯示地轉(zhuǎn)換類型拨齐,這樣只有類型相同的值才能比較:
>>> val x = 1
>>> println(x.toLong() in listOf(1L,2L,3L))
當(dāng)你使用數(shù)字字面值去初始化一個類型已知的變量時,又或時把字面值作為實參傳給函數(shù)時昨寞,必要的轉(zhuǎn)換會自動地發(fā)生。下面代碼并沒有任何顯式轉(zhuǎn)換厦滤,但可以正確地工作:
fun foo(l : Long) = println(1)
>>> val b : Byte = 1
>>> val l = b + 1L
>>> foo(42)
“Any”和“Any?”:根類型
和Object作為Java類層級結(jié)構(gòu)的根差不多援岩,Any類型是Kotlin所有非空類型的超類型(非空類型的根)。
和Java一樣掏导,把基本數(shù)據(jù)類型的值賦給Any類型的變量時會自動裝箱:
val answer : Any = 42
注意Any是非空類型享怀,所以Any類型的變量不可以持有null值。在Kotlin中國如果你需要可以持有任何可能值的變量趟咆,包括null在內(nèi)添瓷,必須使用Any?類型.
所有Kotlin類下面都包含三個方法: toString, equals和hashCode. 這些方法都繼承自Any.
Unit類型: Kotlin的”void”
Kotlin中的Unit類型完成了Java中的void一樣的功能。當(dāng)函數(shù)沒有什么有意思的結(jié)果要返回時值纱,它可以用作函數(shù)的返回類型:
Fun f() : Unit{ … }
語法上鳞贷,它和下面不帶返回值的函數(shù)一樣
fun f(){ … }
那么Kotlin的Unit和Java的void到底有什么不一樣呢? Unit是一個完備的類型,可以作為類型參數(shù)虐唠,而void卻不行搀愧。當(dāng)你在重寫返回泛型參數(shù)函數(shù)時這非常有用,只需要讓方法返回Unit類型的值:
Interface Processor<T>{
fun process() : T
}
Class NoResultProcessor : Processor<Unit>{
override fun process(){
// do stuff
}
}
接口簽名要求process函數(shù)返回一個值:而且Unit類型確實有值,所以從方法中返回它并沒有問題咱筛。然而你不需要在process函數(shù)中寫上顯式的return語句, 因為編譯器會隱式地加上return Unit.
Nothing類型:”這個函數(shù)永不返回”
對于某些Kotlin函數(shù)來說搓幌,“返回類型”的概念沒有任何意義,因為它們從來不會成功地結(jié)束迅箩。例如溉愁,有些測試庫有一個叫做fail的函數(shù),它通過拋出帶有特定消息的異常來讓當(dāng)前測試失敗饲趋。
當(dāng)分析調(diào)用這樣函數(shù)的代碼時拐揭,知道函數(shù)永遠(yuǎn)不會正常終止是很有幫助的。Kotlin使用一種特殊的返回類型Nothing來表示:
fun fail(message : String) : Nothing{
throw IllegalStateException(message)
}
>>> fail(“Error occurred”)
Java.lang.IllegalStateException : Error occurred
返回Nothing的函數(shù)可以放在Elvis運算符的右邊來做先決條件檢查:
val address = company.address ?: fail(“No address”)
println(address.city)
這里我們設(shè)計到了Kotlin基本數(shù)據(jù)類型篙贸,數(shù)字類型之間的轉(zhuǎn)換投队,Unit類型還有Nothing類型.