網上學習kotlin的資料已經很多了镀首,我也不打算復述缸榄,此文僅記錄我學習過程中遇到的我所認為需要記錄的知識點,所以此文并不適合沒有任何Kotlin基礎的學習者衫哥。
inline(內聯(lián)函數)
了解內聯(lián)函數需要的先前概念有:函數士袄、函數調用流程悲关;
函數此處不表。程序在順序執(zhí)行的過程中遇到函數調用娄柳,首先要保護現場(壓棧)->跳轉到函數執(zhí)行處->恢復現場(出棧)(*此處并沒有詳細展開大概知道流程即可)寓辱,這樣一進一出無疑損耗了性能,于是乎產生了內聯(lián)函數赤拒。
內聯(lián)函數并沒有壓棧出棧的操作秫筏,而是直接將內聯(lián)函數的函數體復制粘貼到了調用的位置,這樣雖然減少了性能損耗挎挖,但是編譯過程中實際的代碼量變大了这敬,這就是簡單的空間換時間。
C蕉朵、C++中可以聲明內聯(lián)函數崔涂,在java中不支持直接聲明,但是jvm會根據情況進行優(yōu)化內聯(lián)始衅。(難怪我之前沒聽過這個概念)
通俗易懂:內聯(lián)函數就將其函數體復制粘貼過來
聲明: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缭保,區(qū)別在于方法名前后多了Activity少了參數Context,一表示通過傳遞的上下文啟動Activity蝙茶,二則是在Activity類中增加了方法名為newIntent()的方法艺骂。(好像與內聯(lián)函數沒多大關系啊隆夯!寫在這里以免遺忘)
noinline
內聯(lián)函數中彻亲,參數需要傳遞給非inline函數時需要加noinline。
因為內聯(lián)函數中所有參數已被inline吮廉,這些參數可以在其他內聯(lián)函數中傳遞,如果加上oninline,則此參數可以go anywhere
reified(泛型聲明)
reified T 表明T是一個類畸肆;reified T:Activity 表明T為Activity的子類
操作符
?
聲明變量時如果不加宦芦?則不能夠賦空值
?.
判斷變量是否為null,是則返回null否則執(zhí)行
!!
判斷變量是否為null轴脐,是則NullPointerException否則執(zhí)行
?:
判斷變量是否為null调卑,是則執(zhí)行否則不
let、apply大咱、with恬涧、run區(qū)別
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主要區(qū)別在于返回值
let圾亏、apply十拣、with封拧、run區(qū)別內容參考:http://www.reibang.com/p/28ce69d58fea
函數
kotlin學習的過程中,發(fā)現一個方法單獨寫在一個文件里夭问,且其他類可以調用當時寫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靜態(tài)聲明
companion object用在類中用于聲明靜態(tài)類、方法刊咳、變量彪见,使用方式與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中并沒有區(qū)分先后次序只有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并無區(qū)別参咙,只是在某些場景下必須用方式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.
提一下
子構造方法必須通過this來調用主構造方法
或者
間接性的通過其他子構造方法來完成净宵。
單例
單例自然是編程中不可缺少的一種設計模式敲才,kotlin單例的寫法非常簡潔
objec SingleInstance{
init{
}
fun do()
}
你不需要去手動初始化,kotlin使用懶加載的方式择葡,首次調用單例時便會初始化紧武,如需初始化操作放在init()里
vararg
它的作用類似java中(int nums..)用于傳遞可變參數
回調的寫法
踩了多次的坑,一定要注意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.
}
})
結束語
本文涉及的內容只是常用知識點敏储,掌握了這些不要期待了能寫多溜的代碼阻星,它只能夠幫助你能夠看懂別人的代碼。