Kotlin基礎(chǔ)語(yǔ)法<二>

學(xué)習(xí)需要一步步進(jìn)行,前面已學(xué)習(xí)過(guò)了部分kotlin基礎(chǔ)語(yǔ)法<Kotlin基礎(chǔ)語(yǔ)法一>
?;A(chǔ)語(yǔ)法的學(xué)習(xí)與總結(jié)會(huì)讓我對(duì)知識(shí)了了解更加深入,也算是對(duì)自己的激勵(lì)吧。

Kotlin-數(shù)組

  1. 數(shù)組在kotlin中的使用Array<T>類(lèi)來(lái)表示
  2. 基本類(lèi)型數(shù)組:ByteArray,LongArray,xxxArray等,這些類(lèi)是基本類(lèi)型數(shù)組,但是跟Array類(lèi)沒(méi)有繼承關(guān)系
  3. 數(shù)組的創(chuàng)建
    • 使用arrayOf()函數(shù)(java的靜態(tài)初始化)
    • 使用arrayOfNulls()函數(shù)(java的動(dòng)態(tài)初始化)
    • 使用emptyArray()函數(shù)
    • 使用Array(size:Int,init:(int)->T)構(gòu)造器
fun main(){
    val arr = intArrayOf(1,2,20,36,45,8)
    for((index,value) in arr:withIndex()){
        println("索引為${index}的元素是:${value}")
    }
}

Kotlin的集合

java中的類(lèi)型 Kotlin中的只讀類(lèi)型 Kotlin中的可變類(lèi)型
Iterator<T> Iterator<T> MutableIterator<T>
Iterable<T> Iterable<T> MutableIterable<T>
Collection<T> Collection<T> MutableCollection<T>
Set<T> Set<t> MutableSet<t>
List<T> List<T> MutableList<T>
ListIterator<T> ListIterator<T> MutableListIterator<T>
Map<K,V> Map<K,V> MutableMap<K,V>
Map.Enrty<K,V> Map.Entry<K,V> MutableMap.MutableEntry<K,V>
  1. kotlin集合可分為可變和不可變集合
  2. 聲明并初始化List的集合,使用listOf(..)函數(shù)
  3. 聲明并初始化MutableList的集合,使用mutableListOf(..)函數(shù)/listOfNotNull()/arrayListOf()
  4. 聲明并初始化Set集合,使用setOf(..)函數(shù)
  5. 聲明并初始化MutableSet的集合,使用mutableSetOf(..)函數(shù)/hashSetOf()/linkedSetOf()/sortedSetOf()
  6. 不可變的Map類(lèi)型的初始化,使用mapOf()函數(shù)
  7. 可變的Map類(lèi)型集合的初始化,使用mutableMapOf()函數(shù)/hashMapOf()/linkedMapOf()/sortedMapOf()

for循環(huán)使用

fun main() {
    val items = listOf("java", "kotlin", "android")
    for (item  in items) {
        println(item)
    }
}
fun main() {
    val items = listOf("java", "kotlin", "android")
    for (index  in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

Kotlin的泛型

先了解一下java的泛型

上界通配符 < ? extends X>。用 extends 關(guān)鍵字聲明,表示參數(shù)化的類(lèi)型可能是所指定的類(lèi)型,或者是此類(lèi)型的子類(lèi)。

上界 ->取出來(lái)的類(lèi)型不會(huì)丟失,存放會(huì)丟失類(lèi)型。(?代表容器里的元素類(lèi)型為X基類(lèi)類(lèi)型,X是所有元素的基類(lèi),存(即set)進(jìn)去就無(wú)法確定是那個(gè)具體的類(lèi)型了,取出來(lái)就沒(méi)有問(wèn)題,因?yàn)閄是表示所有基類(lèi))

下界通配符 < ? super E>。用 super 進(jìn)行聲明,表示參數(shù)化的類(lèi)型可能是所指定的類(lèi)型,或者是此類(lèi)型的父類(lèi)型,直至 Object。

下界 ->取出來(lái)的類(lèi)型會(huì)丟失,存放不會(huì)丟失類(lèi)型。(?代表容器里的元素類(lèi)型為E基類(lèi)類(lèi)型,存(即set)進(jìn)去的都是E的超類(lèi),取出來(lái)就不知道是那個(gè)具體的類(lèi)型,這樣就沒(méi)法統(tǒng)一基類(lèi)類(lèi)型了,全部都為Object)

上界、下界遵循PECS (Producter Extends Consumer Super)

Producter 產(chǎn)生者 -> 取
Consumer 消費(fèi)者 -> 存

詳細(xì)的java泛型

Kotlin的泛型 jvm泛型從java中繼續(xù)過(guò)來(lái)的

out(相當(dāng)于java的上界)取出來(lái)是沒(méi)有問(wèn)題,存進(jìn)去就有問(wèn)題。 out在Kotlin中叫協(xié)變。

in(相當(dāng)于java的下界)存進(jìn)去沒(méi)有問(wèn)題,取出來(lái)就是問(wèn)題。 in在Kotlin中叫逆變。

有一個(gè)copy數(shù)組的函數(shù),看如下代碼:

fun copy(destArr:Array<Double>,srcArr:Array<Double>){
}

fun main(){
    var destDouble = arrayOf<Double>()
    var srcDouble = arrayOf<Double>(1.1,2.2,3.3)
    copy(destDouble,srcDouble)
}

如果有多種類(lèi)型的數(shù)組要copy,那么copy函數(shù)就得復(fù)寫(xiě)多個(gè)。復(fù)寫(xiě)多個(gè)copy函數(shù),這樣寫(xiě)代碼臃腫,也不優(yōu)雅??聪旅娲a如何優(yōu)雅實(shí)現(xiàn)根據(jù)不同類(lèi)型實(shí)現(xiàn)copy函數(shù)。

//泛型函數(shù)   泛型
fun <T> copy(destArr:Array<T>,srcArr:Array<T>){
}

fun main(){
    var destDouble = arrayOf<Double>()
    var srcDouble = arrayOf<Double>(1.1,2.2,3.3)
    copy(destDouble,srcDouble)

    var destInt = arrayOf<Int>()
    var srcInt = arrayOf(1,2,3)
    copy(destInt,srcInt)
}

不錯(cuò)上述的copy函數(shù)就是使用了泛型,也是一個(gè)簡(jiǎn)單的使用。copy這個(gè)泛型函數(shù),還是存在問(wèn)題的,Int/Double的父類(lèi)為Number。如果destArrc參數(shù)傳入一個(gè)arrayOf<Number>數(shù)組,那么copy函數(shù)就報(bào)錯(cuò)了。這個(gè)問(wèn)題也很容易解決,把srcArr存放到destArr數(shù)組中,那么把destArr的泛型改為逆變就可以了(destArr:Array<in T>)。如下代碼:

fun <T> copy(dest:Array<in T>,src:Array<T>){
    //把srcArr的內(nèi)容拿出來(lái),存放到destArr數(shù)組中
    srcArr.forEachIndexed{ index,value->destArr[index] = srcArr[index]}
}
fun main(){
    var srcInt = arrayOf(1,2,3)
    var destNum = arrayOf<Number>(3)
    copy(destNum,srcInt)
}

上述的dest:Array<in T>,in T ( 相當(dāng)于java中的 ?super T)是一個(gè)逆變。逆變之后,可以把Array<Number>理解為Array<Int>/Array<Double>的子類(lèi)。上面的copy泛型函數(shù)寫(xiě)法還寫(xiě)成另一種,代碼如下:

fun <T> copy(dest:Array<T>,src:Array<out T>){
    //把srcArr的內(nèi)容拿出來(lái),存放到destArr數(shù)組中
    srcArr.forEachIndexed{ index,value->destArr[index] = srcArr[index]}
}

fun main(){
    var srcInt = arrayOf(1,2,3)
    var destNum = arrayOf<Number>(3)
    copy(destNum,srcInt)
}

copy(dest:Array<T>,src:Array<out T>)是協(xié)變的寫(xiě)法。src:Array<out T>取出來(lái)的類(lèi)型一定是T類(lèi)型,所以存放到destArr<T>是沒(méi)有問(wèn)題的。

特別例子:在java不允許泛型使用方式,而在kotlin中可以使用

java中不允許泛型使用的方式,代碼如下:

public class A{
    interface Callback<T>{//聲明處形變 
        T getT();
    }
    interface Call<? extends K>{//聲明處形變 是不允許這樣使用的  無(wú)法聲明處形變的 
    }
    void test(Callback<String> callback){
        Callback<String> cb = callback;//java 是不允許這樣使用的
    }
}

kotlin中可以使用java中不允許泛型使用的方式,代碼如下:

interface Callback<out T>{
    fun getT():T
}

fun test(src:Callback<String>){
    val dest:Callback<Any?> = src
}

從上述兩處代碼得出:kotlin對(duì)java的泛型的增強(qiáng),多了一個(gè)聲明處形變。

Kotlin的lambda

{ }就是表示一個(gè)lambda表達(dá)式

fun main(){
    var sum ={x:Int,y:Int -> x+y}
    //lambda表達(dá)式調(diào)用
    com.lu.kotlindemo.testFun.sum(1,3) 
}
fun main(){
    var temp:(Int,Int)->Int  //相當(dāng)于 var temp:Any
    //這是一個(gè)lambda { }
    temp ={x:Int,y:Int -> x+y}
    val sum = temp.invoke(2,2)
    println("相加:${sum}")

    temp ={x:Int,y:Int -> x*y}
    val c = temp.invoke(3,4)
    println("相乘:${c}")

    //這也是一個(gè)lambda
    var tmp :(Int)->Unit 
    tmp ={ println("$it")}//這個(gè)it代表只有一個(gè)參數(shù)(默認(rèn)只有一個(gè)參數(shù))
}

var temp:(Int,Int)->Int 。聲明處用括號(hào)括起來(lái),也是就是定義一個(gè)類(lèi)型 ,傳入兩個(gè)Int類(lèi)型參數(shù)并返回一個(gè)Int類(lèi)型值。相當(dāng)于 var temp:Any。

tmp ={ println("$it")},注意:這個(gè)it代表只有一個(gè)參數(shù)(默認(rèn)只有一個(gè)參數(shù))。如果有返回值,最后一句就是代表返回值,不能要{}里面return。

錯(cuò)誤代碼:

tmp ={
    println("$it")
    return //不能夠這樣寫(xiě)return
}

正確代碼:

tmp ={
    println("$it")
    it+3 //最后一句 代表返回值
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容