Kotlin學習中觸碰到的知識點

網上學習kotlin的資料已經很多了,我也不打算複述,此文僅記錄我學習過程中遇到的我所認爲需要記錄的知識點,所以此文並不適合沒有任何Kotlin基礎的學習者。

inline(內聯函數)


瞭解內聯函數需要的先前概念有:函數、函數調用流程;

函數此處不表。程序在順序執行的過程中遇到函數調用,首先要保護現場(壓棧)->跳轉到函數執行處->恢復現場(出棧)(*此處並沒有詳細展開大概知道流程即可),這樣一進一出無疑損耗了性能,於是乎產生了內聯函數。

內聯函數並沒有壓棧出棧的操作,而是直接將內聯函數的函數體複製粘貼到了調用的位置,這樣雖然減少了性能損耗,但是編譯過程中實際的代碼量變大了,這就是簡單的空間換時間。

C、C++中可以聲明內聯函數,在java中不支持直接聲明,但是jvm會根據情況進行優化內聯。(難怪我之前沒聽過這個概念)

通俗易懂:內聯函數就將其函數體複製粘貼過來

聲明:inline fun <泛型> 函數名(參數:類型,…..):返回類型{}

舉個例子:


inline fun <reified T: Activity> newIntent(context:Context) {

val intent = Intent(context,T::class.*java*)

context.startActivity(intent)

}

inline fun <refied T: Activity> Activity.newIntent() {

valintent = Intent(this,T::class.*java*)

startActivity(intent)

}

一與二的功能相同都是啓動Activity,區別在於方法名前後多了Activity少了參數Context,一表示通過傳遞的上下文啓動Activity,二則是在Activity類中增加了方法名爲newIntent()的方法。(好像與內聯函數沒多大關係啊!寫在這裏以免遺忘)

noinline


內聯函數中,參數需要傳遞給非inline函數時需要加noinline。

因爲內聯函數中所有參數已被inline,這些參數可以在其他內聯函數中傳遞,如果加上oninline,則此參數可以go anywhere

reified(泛型聲明)


reified T 表明T是一個類;reified T:Activity 表明T爲Activity的子類

操作符


    ? 

聲明變量時如果不加?則不能夠賦空值

image

image

    ?.

判斷變量是否爲null,是則返回null否則執行

    !!

判斷變量是否爲null,是則NullPointerException否則執行

image

    ?:

判斷變量是否爲null,是則執行否則不

image

操作符內容參考:http://www.mamicode.com/info-detail-1901808.html

let、apply、with、run區別


let


object.let{

    do(it)

    it.toString()

    return 0

}

默認當前這個對象object作爲函數裏it的參數,it既是object。

如果函數裏有return 則返回return 內容,否則返回最後一行內容。

假設最後一行是 it.toString(),則返回String

apply


object.apply{

    do()

}

函數內do()方法實際是object的方法,即object.do()。

返回的是object對象。

with


with(object){

    do()

    toString()

}

函數內do()方法實際是object的方法,即object.do()。

返回的是最後一行,即String。

run


object.run{

    do()

}

函數內do()方法實際是object的方法,即object.do()。

返回的是對象本身,即object。

let、apply、with、run主要區別在於返回值

let、apply、with、run區別內容參考:http://www.jianshu.com/p/28ce69d58fea

函數


kotlin學習的過程中,發現一個方法單獨寫在一個文件裏,且其他類可以調用當時寫java的我很是疑惑。

    擴展函數

直接定義在文件中的函數,不需要依賴其他類。通常項目中的擴展函數存在於一個文件中。

    成員函數

定義在類中的函數。

    本地函數

定義在函數內部的函數。

open


這個關鍵字用來標識可被繼承和重寫。

java中類選定好了父類就可以繼承並重寫父類方法,但kotlin要嚴謹,可被繼承父類必須加上open關鍵字,需要重寫但方法也要加上open關鍵字。

abstract類默認有open關鍵字所以不需要手動加。

as與as?


看似相似實則功能不同

as?用於類型強轉但它不會ClassCastException,如果強轉失敗則會返回null

as類似C語言中typedef,給類起別名。用於同名不同類同時出現在一起的情況,增加代碼可讀性。

data class


用於生成數據類,自動生成get()、set()、equals()、hashCode()、toString()、copy()等。

主構造方法至少有一個參數。

值得一提的是componentN()方法,數據類有幾個參數componentN()方法就有幾個N取整數,例如component1()。

companion object靜態聲明


companion object用在類中用於聲明靜態類、方法、變量,使用方式與java static關鍵字類似


class Class1 {

    companion object Factory{

        fun create(): MyClass = MyClass()

    }

}

class Class2 {

    companion object{

        fun create(): MyClass = MyClass()

    }

}

Class1與Class2同效


使用方式1

var object = Class1.create()

使用方式2

var object =Class1.Factory.create()

Class1可以使用方式1和方式2,Class2就只能使用方式1

運算符


具體的運算符列表此處不表,網上到處都是,有一元運算符、二元運算符,唯獨沒有三元運算符。

這裏說一下a++、a–與++a、–a,在kotlin中並沒有區分先後次序只有inc()和dec(),官方文檔中說(我的白話):

a++操作先定義一個變量a0,給a0賦值爲a,給a賦值爲a.inc(),然後返回a0;

++a操作直接給a賦值爲a.inc(),然後返回a;

個人認爲官方文檔什麼都沒有解釋,只是給出了編程道路最初遇到的++a和a++的大難題,至於inc()和dec()怎麼實現先後問題完全沒給解釋。(要不就是我英語太差,沒讀懂,託福雅思的大神勿噴我)

操作符:http://blog.csdn.net/love667767/article/details/72589260

::class


第一次見到是不是很奇怪,Hello::class和Hello::class.java都是什麼鬼啊!kotlin中類爲KClass,java中類爲Class。在kotlin中獲取KClass方式爲Hello::class,若要將其改爲Class就需要Hello::class.java。

類和對象


kotlin中一個類有一個主構造方法和若干子構造方法


方式1

class People constructor(name:String , age :int){

}

方式2

class People (name:String , age :int){

}

方式1和方式2並無區別,只是在某些場景下必須用方式1,例如註解。

有了構造函數並不代表實例化出來的對象屬性已經賦值了


方式1

class People constructor(name:String , age :int){

    var name: String

    var age:int

    init{

        this.name=name

        this.age=age

    }

}

方式2

class People (var name:String , var age :int){

}

方式1聲明屬性,並在init()中初始化。方式2直接在主構造方法中聲明屬性,可用val或var.

image

提一下

子構造方法必須通過this來調用主構造方法

或者

間接性的通過其他子構造方法來完成。

單例


單例自然是編程中不可缺少的一種設計模式,kotlin單例的寫法非常簡潔


objec SingleInstance{

    init{

    }

    fun do()

}

你不需要去手動初始化,kotlin使用懶加載的方式,首次調用單例時便會初始化,如需初始化操作放在init()裏

vararg


它的作用類似java中(int nums..)用於傳遞可變參數

image

回調的寫法


踩了多次的坑,一定要注意object是關鍵字

        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            override fun surfaceDestroyed(holder: SurfaceHolder?) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            override fun surfaceCreated(holder: SurfaceHolder?) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

        })

結束語


本文涉及的內容只是常用知識點,掌握了這些不要期待了能寫多溜的代碼,它只能夠幫助你能夠看懂別人的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章