Android:Kotlin语法基础
主函數
fun main(args: Array<String>){println("Hello World") } 復制代碼變量
1、常量
val修飾常量,編譯器規定常量必須初始化,若不想初始化,可用**by lazy{}**對常量進行懶加載
val a: Int = 1 // 強類型常量 val b = 2 // 弱類型常量 const val c = "Hello" // 編譯器常量 val a: String by lazy{"lazy init"} // 懶加載常量 復制代碼2、變量
var修飾變量,編譯器規定變量必須初始化,若不想初始化,可用lateinit關鍵字限制報錯
lateinit var a //未初始化變量var x = 5 //初始化變量 var x1 = "x is $x" //獲取變量的值:$變量 var x2 = "${x1.replace("is","was")}" //內嵌表達式:${表達式}var str = """ //段落<html><a href="">go</a></html> """ 復制代碼3、空值檢測
println(value?.size) //if not null println(value?.size ?: "empty") //if not null and else println(value.firstOrNull() ?: "") //if not null and get first println(values["key"] ?: a + b) //if not null and else + 表達式 value?.let{ } //if not null + 代碼塊 value!!.let{ } //告訴編譯器不需要判空 復制代碼4、字符串比較
==:在kt中相當于java的equals() ===:在kt中相當于java的==
數組
1、定義
//每種基本類型都有對應的數組創建方法,類似于定制版 var array:IntArray = intArrayOf(1,3,5,7) var array:CharArray = charArrayOf('H','E','L','L','O') //基于泛性的創建方法,泛型也可省略,類似于通用版 var array:Array<Char> = arrayOf('H','E','L','L','O') 復制代碼2、數組和字符串轉換
//第一種形式 var array:Array<Char> = arrayOf('H','E','L','L','O') println(array.joinInString("")) //第二種形式 var array:CharArray = charArrayOf('H','E','L','L','O') println(String(array)) 復制代碼3、數組遍歷
var array:Array<Char> = arrayOf('H','E','L','L','O') //第一種形式 array.forEach{println(it)} //第二種形式 array.forEach{::println} //第三種形式 for((index,value) in array.withIndex()){println("$index -> $value") } 復制代碼函數
1、有返回值的函數
//第一種形式 fun sum(a: Int, b: Int): Int {return a + b} //第二種形式 fun sum(a: Int, b: Int) = return a + b //第三種形式 fun sum(a: Int, b: Int) = a + b 復制代碼2、無返回值的函數
Unit類型相當于Void類型,Unit返回類型可以省略不寫
fun printSum(a: Int, b: Int): Unit { …… } 復制代碼3、默認參數的函數
fun foo(a: Int = 0, b: String = "") { …… } 復制代碼4、變長參數的函數
變長參數由vararg關鍵字決定,數組參數可通過*方式傳參,第一個參數可以不使用名字指定,最后個參數必須使用具名參數
fun say(double: Double,vararg ints: Int,string: String) { …… }val array = intArrayOf(1,3,4,5) say(2.0,*array,string = "Hi") 復制代碼5、擴展函數
你可以給父類添加一個方法,這個方法將可以在所有子類中使用
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {Toast.makeText(this, message, duration).show() } 復制代碼6、智能類型推測
判斷一個對象是否為一個類的實例,可以使用is關鍵字與Java中的instanceof關鍵字類似,但在Kotlin中如果已經確定了一個對象的類型,可以在接下來的代碼塊中直接作為這個確定類型使用
fun getStringLength(obj: Any): Int? {if (obj is String) {return obj.length} //類型判斷后,obj會被系統自動轉換為String類型if (obj !is String){} //同時還可以使用!is,來取反return null //代碼塊外部的obj仍然是Any類型的引用 } 復制代碼7、復合函數
復合函數指的是函數中存在另一個函數,類似于數學的f(g(x))
infix fun <P1,P2,R> Function1<P1,P2>.andThen(function: Function1<P2,R>): Function1<P1,R>{return fun(p1:P1): R{return function.invoke(this.invoke(p1))} }var add = {i: Int -> i + 5} var plus = {i: Int -> i * 2} var addAndPlus = add andThen plus println(addAndPlus(8)) // (8+5)*2=26 復制代碼8、函數的科理化
函數的科理化指的是函數中傳遞的多個參數可轉換為多個函數來進行鏈接
//科理化前的函數 fun log(tag: String,target: OutputStream,message: Any?){target.write("$tag $message\n".toByteArray()) } log("Hensen",System.out,"HelloWorld")//科理化后的函數 fun log(tag: String)= fun(target: OutputStream)= fun(message: Any?)= target.write("$tag $message\n".toByteArray()) log("Hensen")(System.out)("HelloWorld") 復制代碼Lambda表達式
1、定義Lambda表達式
var sum = {arg1: Int,arg2: Int ->arg1 + arg2 } //使用第一種方式 sum(1,2) //使用第二種方式 sum.invoke(1,2) 復制代碼2、帶有return的Lambda表達式
Lambda表達式并不是函數,如果直接return,會退出當前調用Lambda表達式的函數,而不是退出當前的Lambda表達式,可以使用**@別名**的方式退出
var array:Array<Char> = arrayOf('H','E','L','L','O') array.forEach ForEach@{if(it == 'L')return@ForEachprintln(it) } 復制代碼3、帶有run的Lambda表達式
調用某對象的run函數,在函數塊內可以通過this指代該對象。返回值為函數塊的最后一行或指定return表達式
val a = "string".run {print(this) //string3 } println(a) //3 復制代碼4、帶有let的Lambda表達式
調用某對象的let函數,則該對象為函數的參數。在函數塊內可以通過it指代該對象。返回值為函數塊的最后一行或指定return表達式
val a = "string".let {println(it) //string3 } println(a) //3 復制代碼5、帶有with的Lambda表達式
它是將某對象作為函數的參數,在函數塊內可以通過this指代該對象。返回值為函數塊的最后一行或指定return表達式
val a = with("string") {println(this) //string3 } println(a) //3 復制代碼6、帶有apply的Lambda表達式
調用某對象的apply函數,在函數塊內可以通過this指代該對象。返回值為該對象自己
val a = "string".apply {println(this) //string } println(a) //string 復制代碼7、帶有also的Lambda表達式
調用某對象的also函數,則該對象為函數的參數。在函數塊內可以通過it指代該對象。返回值為該對象自己
val a = "string".also {println(it) //string } println(a) //string 復制代碼8、小結
- run:使用this指定當前對象,最后一行為返回值
- let:使用it指定當前對象,最后一行為返回值
- with:使用this指定當前對象,最后一行為返回值,寫法上有區別
- apply:使用this指定當前對象,返回值為該對象自己
- also:使用it指定當前對象,返回值為該對象自己
表達式
1、When表達式
fun transform(x: Int){return when (x) {is Int -> println("$x is Int")in 1..100 -> println("$x is in 1-100")!in 1..100 -> println("$x is not in 1-100")//else不寫則不做默認操作else -> throw IllegalArgumentException("Invalid x param value")} } 復制代碼或者
fun describe(obj: Any): String =when (obj) {1 -> "One""Hello" -> "Greeting"is Long -> "Long"!is String -> "Not a string"else -> "Unknown" } 復制代碼2、try-catch表達式
fun test() {val result = try {count()} catch (e: ArithmeticException) {throw IllegalStateException(e)} } 復制代碼3、if表達式
fun foo(param: Int) {val result = if (param == 1) {"one"} else if (param == 2) {"two"} else {"three"} } 復制代碼4、with表達式
class Turtle {fun penDown()fun penUp()fun turn(degrees: Double)fun forward(pixels: Double) }val myTurtle = Turtle() with(myTurtle) { // 畫一個 100 像素的正方形penDown()for(i in 1..4) {forward(100.0)turn(90.0)}penUp() } 復制代碼5、for表達式
val items = listOf("apple", "banana", "kiwifruit") for (item in items) {println(item) }val items = listOf("apple", "banana", "kiwifruit") for (index in items.indices) {println("item at $index is ${items[index]}") } 復制代碼6、while表達式
val items = listOf("apple", "banana", "kiwifruit") var index = 0 while (index < items.size) {println("item at $index is ${items[index]}")index++ } 復制代碼7、中綴表達式
使用infix關鍵字創建中綴表達式
Class Book{infix fun on(any: Any): Boolean{return false} }Class Desk{}if(Book on Desk){println("book on the desk") } 復制代碼閉包
1、函數內部可以定義函數,屬于閉包
fun add(x: Int): (Int)-> Int{return fun(y: Int): Int{return x + y} } 復制代碼2、閉包持有函數內部的運行狀態
fun justCount():() -> Unit{var count = 0 //被函數內部持有return {println(count++)} }fun main(args: Array<String>) {val count = justCount()count() // 輸出結果:0count() // 輸出結果:1count() // 輸出結果:2 } 復制代碼3、自行閉包
自執行閉包就是在定義閉包的同時直接執行閉包,一般用于初始化上下文環境
{ x: Int, y: Int ->println("${x + y}") }(1, 3) 復制代碼運算符
1、自定義運算符
class Complex(var arg1: Double,var arg2: Double){operator fun plus(other: Complex): Complex{return Complex(arg1 + other.arg1,arg2 + other.arg2)}operator fun plus(other: Int): Complex{return Complex(arg1 + other,arg2)}oprator fun invoke(): Double{return Math.hypot(arg1,arg2)}overide fun toString(): String{return "${arg1} and ${arg2}"} }val c1 = Complex(3.0,4.0) val c1 = Complex(2.0,5.0) println(c1 + c2) //5.0 and 9.0 println(c1 + 5) //8.0 and 4.0 println(c1()) //5 復制代碼區間語句
1、定義區間
var range = 0..1024 //[0,1024]閉區間 var range = 0 until 1024 //[0,1024)半開區間 var range = 0..-1 //空區間 復制代碼2、檢查x是否在指定區間里面
val x = 10 val y = 9 if (x in 1..y+1) {println("fits in range") } 復制代碼3、檢查list.size是否在list的索引上
val list = listOf("a", "b", "c")if (-1 !in 0..list.lastIndex) {println("-1 is out of range") } if (list.size !in list.indices) {println("list size is out of valid list indices range too") } 復制代碼4、區間遍歷
for (x in 1..10 step 2) {print(x) //13579 } for (x in 9 downTo 0 step 3) {print(x) //9630 } 復制代碼集合
1、初始化
val mutableList = mutableListOf(0, 1) //可讀寫List對象 var list = listOf(0, 1, 2) //可讀List對象 val set = setOf(1, 2, 4) //可讀Set對象 復制代碼2、集合遍歷
val items = listOf("a", "b", "c") for (item in items) {println(item) } 復制代碼3、集合判斷
val items = listOf("apple", "balanace", "coffee") when {"orange" in items -> println("juicy")"apple" in items -> println("apple is fine too") } 復制代碼映射
1、初始化
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3) //可讀寫Map對象 val map = mapOf("a" to 1, "b" to 2, "c" to 3) //可讀Map對象 復制代碼2、訪問Map
map["key"] = value 復制代碼3、遍歷Map
for ((k, v) in map) {println("$k -> $v") } 復制代碼構造方法
1、主構造函數
Kotlin的構造函數可以寫在類頭中,跟在類名后面,如果有注解還需要加上關鍵字constructor
class Person(private val name: String) {fun sayHello() {println("hello $name")} } 復制代碼在主構造函數中不能有任何代碼實現,如果有額外的代碼需要在構造方法中執行,你需要放到init代碼塊中執行
class Person(private var name: String) {init {name = "Zhang Tao"}fun sayHello() {println("hello $name")} } 復制代碼2、次構造函數
存在兩個或兩個以上的構造方法時,可以增加次構造方法
class Person(private var name: String) {private var description: String? = nullinit {name = "Zhang Tao"}constructor(name: String, description: String) : this(name) {this.description = description}fun sayHello() {println("hello $name")} } 復制代碼類與對象
1、輸出類名
println(HelloWorld::class.java.simpleName) //輸出類名 println(HelloWorld::class.java.name) //輸出包名+類名 復制代碼2、創建對象
val rectangle = Rectangle(5.0, 2.0) val triangle = Triangle(3.0, 4.0, 5.0) 復制代碼3、數據類
data修飾的類稱之為數據類,當data修飾后,會自動將所有成員用operator聲明,即為這些成員生成getter()和setter()
data class Customer(val name: String, val email: String) 復制代碼編譯器自動從主構造函數中的屬性導入下面這些成員函數
equals() hashCode() toString() componentN():函數返回對應著聲明的參數順序 copy() 復制代碼4、內部類
Kt默認的內部類為靜態內部類,可以使用inner關鍵字將內部類變為非靜態內部類,且可使用注解去獲取外部類的成員屬性
class Outter{var a = 5inner class Inner{var a = 6fun getOutterA(){println(this@Outter.a)}} } 復制代碼5、單例類
object關鍵字表示該類是單例
class Single private constructor() {companion object {fun get():Single{return Holder.instance}}private object Holder {val instance = Single()} } 復制代碼或者
object Resource {val name = "Name" } //使用 Resource.INSTANCE.name 復制代碼6、枚舉類
枚舉默認沒有數值,如果需要固定類型的數值,可在類名后聲明參數類型
enum class Programer(val id: Int) {JAVA(0), KOTLIN(1), C(2), CPP(3), ANDROID(4);fun getTag(): String{return "$id + $name"} } //使用 println(Programer.JAVA.getTag()) 復制代碼7、密封類
sealed修飾的類稱為密封類,用來表示受限的類層次結構
sealed class BaseClass {class Test1 : BaseClass() {override fun test() {println("Test1實例")}}class Test2 : BaseClass() {override fun test() {println("Test2實例")}}object Test3 : BaseClass() {override fun test() {println("Test3實例")}}open fun test() {println("BaseClass實例")} } 復制代碼密封類與枚舉的區別:
密封類是枚舉類的擴展 枚舉類型的值集合是受限的,且每個枚舉常量只存在一個實例 密封類的一個子類可以有可包含狀態的多個實例 8、繼承
在class中加open關鍵字即可被繼承
open class Person(var name:String, var age:Int){} 復制代碼9、接口代理
接口代理表示代理人可直接調用接口代理的方法
//代理driver和writer,當執行manager.driver(),Manager類會去調用代理的driver.driver() class Manager(val driver: Driver,val writer: Writer):Driver by driver,Writer by writerinterface Driver{fun driver()} interface Wirter{fun wirter()} 復制代碼10、伴生對象
用companion關鍵字修飾對象內的方法,我們稱companion修飾的對象為伴生對象,本質是靜態方法。如果在Java文件中想通過類名的方式去調用靜態方法,則需要加入注解才可以使用
class StringUtils {companion object {@JvmStaticfun isEmpty(str: String): Boolean {return "" == str}@JvmFieldvar TAG = "StringUtils"} } 復制代碼11、方法重載
由于Kt中有默認參數的性質,所以方法的重載可以用默認參數來實現,如果在Java文件中想使用Kt重載的話,就需要加入注解才可以使用
class StringUtils {@JvmOverloadsfun a(int: Int = 0): Int{return int} } 復制代碼12、匿名對象
使用object對象表示匿名對象
btn?.setOnClickListener(object : View.OnClickListener{override fun onClick(v: View?) {} }) 復制代碼常用操作符
Kotlin的操作符跟RxJava基本一致
1、下標操作類
- contains:判斷是否有指定元素
- elementAt:返回對應的元素,越界會拋IndexOutOfBoundsException
- firstOrNull:返回符合條件的第一個元素,沒有返回null
- lastOrNull:返回符合條件的最后一個元素,沒有返回null
- indexOf:返回指定元素的下標,沒有 返回-1
- singleOrNull:返回符合條件的單個元素,如有沒有符合或超過一個,返回null
2、判斷類
- any:判斷集合中 是否有滿足條件的元素
- all:判斷集合中的元素是否都滿足條件
- none:判斷集合中是否都不滿足條件,是則返回true
- count:查詢集合中滿足條件的元素個數
- reduce:從第一項到最后一項進行累計
3、過濾類
- filter:過濾 掉所有滿足條件的元素
- filterNot:過濾所有不滿足條件的元素
- filterNotNull:過濾NULL
- take:返回前n個元素
4、轉換類
- map:轉換成另一個集合
- mapIndexed:除了轉換成另一個集合,還可以拿到Index
- mapNotNull:執行轉換前過濾掉 為 NULL 的元素
- flatMap:自定義邏輯合并兩個集合
- groupBy:按照某個條件分組,返回Map
5、排序類
- reversed:反序
- sorted:升序
- sortedBy:自定義排序
- sortedDescending:降序
6、實戰操作符
val fruits = listOf("banana", "avocado", "apple", "kiwifruit") fruits.filter { it.startsWith("a") }.sortedBy { it }.map { it.toUpperCase() }.forEach { println(it) } 復制代碼特性
1、懶加載
val p: String by lazy {// 計算該字符串 } 復制代碼2、安全類型轉換
父類轉成子類會拋出類型轉換失敗的錯誤,如果采用**as?**的方式,則返回null
var child: Child = parent as? Child 復制代碼3、輸出可執行文件
在Gradle添加依賴指定main函數文件,后綴名為Kt
apply plugin:'application' mainClassName = "com.hensen.android.MyCalcKt" 復制代碼刷新Gradle,在Gradle右邊欄點擊distribution/installDist,生成的程序在build/install目錄下
4、internal關鍵字
在變量中使用internal關鍵字表示成員變量只允許在模塊內能被訪問到
internal var name 復制代碼5、尾遞歸
對于遞歸函數,如果遞歸函數并未對遞歸的結果進行操作,則可以使用tailrec關鍵字將遞歸聲明為尾遞歸,尾遞歸會優化代碼,將遞歸轉換成迭代
data class ListNode(val value: Int,var next: ListNode?) //對遞歸的結果并未操作,屬于尾遞歸 tailrec fun findListNode(head: ListNode?,value: Int): ListNode?{head?: return nullif(head.value == value) return headreturn findListNode(head.next,value) } //對遞歸的結果進行乘法運算,不屬于尾遞歸 fun factorial(n: Long): Long{return n * factorial(n - 1) } 復制代碼Android相關
1、view.find
使用Ktolin的拓展函數,view.find替代findViewById
var textView = view.find(R.id.textView) 復制代碼2、observable
Delegates.observable可以監聽當前的變量值的變化,改變變量的值,即可觸發observable
private var mCurrentState: Int by Delegates.observable(-1) { _, old, new ->if (old != new) {RxBus.getDefault().post(ChannelPK_OnModelChange_Rank_EventArgs(new == 1))MLog.info(PKModelManager.TAG, "rank mode : $old -> $new")} }fun onModelChange() {mCurrentState = 1 //改變變量的值,即可觸發observable } 復制代碼3、bundle
創建bundle已經不需要再去執行其各種put方法
val bundle = bundleOf("KET_INT" to 1,"KET_LONG" to 2L,"KET_BOOLEAN" to true,"KEY_NULL" to null,"KEY_ARRAY" to arrayOf(1, 2) ) 復制代碼4、Parcelize
Parcelize已經不需要再寫什么代碼了,只需要繼承和注解
@Parcelize data class User(val name: String,val age: Int): Parcelize 復制代碼@Parcelize的使用需要在gradle聲明變量androidExtensions {experimental = true } 復制代碼5、Serializable
指定Serializable的名字
class Book(@SerializedName(TXT) var txt: String) 復制代碼6、postDelay
postDelay支持閉包和lambda表達式
handler.postDelayed(50) {// lambda } 復制代碼7、注解
如果說在Java文件中需要使用到KT的變量、靜態方法、重載方法等,就需要注解聲明
- @JvmField:將屬性編譯為Java變量
- @JvmStatic:將伴生對象編譯為Java靜態方法
- @JvmOverloads:默認參數生成重載方法
- @file:JvmName:指定Kotlin文件編譯后的類名
轉載于:https://juejin.im/post/5cd58088f265da039b088aef
總結
以上是生活随笔為你收集整理的Android:Kotlin语法基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方舟手游墓碑怎么捡包 方舟生存进化
- 下一篇: 全民k歌唱完的歌保存在哪里(全民直播倒闭