1. 程式人生 > >(一)Kotlin 基礎語法

(一)Kotlin 基礎語法

文章目錄

一、 Kotlin語法

1. 變數與常量

<修飾符> <變數/常量名>[:型別]=[值]

*注:[]中的內容可省略,編譯器可進行型別推導得出

在一般情況下:[型別]可省略,編譯器進行型別推導

* 常量:
//val 修飾的為常量,不可再次賦值
val FINAL_HELLO_WORLD :String = "Hello World"

val USER_TYPE = "Admin"
* 變數:
//var 修飾的為變數,值可變化
var index:Int =1
//index 自增
index++ 

var username="ZhangSan"
* 字串模板:

在Kotlin中可使用字串模板來實現字串中輸出變數/常量值

var username="ZhangSan"
fun main(args:Array<String>){
    username = args[0]
    println("歡迎 ${username} 登入系統!")
}

2. 函式(得函式者得天下)

  • [函式修飾符] [函式名稱]([引數列表])[:返回值型別]{[函式體]}
  • [函式修飾符] [函式名稱]([引數列表])=[表示式]

*注:[]中的內容可省略,編譯器可進行型別推導得出

/**
 * 根據時間字串返回日期
 */
private fun getDate(dateStr:String): Date {
    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    return sdf.parse(dateStr)
}


/**
 * 傳入兩個整形數,計算他們的和並輸出
 */
fun add(num1:Int,num2:Int){
    println("$num1 + $num2 = ${num1+num2}")
}

/**
 * 傳入姓名,輸出 Hi [傳入的姓名]
 */
fun sayHi(name:String)=println("Hi $name")


  • 匿名函式

匿名函式就是沒有函式名稱的函式,但是匿名函式必須賦值給一個變數/常量

/**
 * 匿名函式
 */
val sayHi = fun(name:String)=println("Hi $name")

3. Lambda 表示式

Lambda 表示式 就是匿名函式

  • 語法:{[引數列表] -> [函式體,最後一行是返回值]}
例如:
val sum = {a:Int,b:Int -> a+b}
  • Lambda 表示式型別表示
/**
 * 無參,返回值為Unit
 */
() -> Unit

/**
 * 傳入整型,返回一個整型
 */
(Int) -> Int

/**
 * 傳入字串、Lambda表示式,返回Boolean
 */
(String,(String) -> String) -> Boolean
  • Lambda 表示式的呼叫

用()進行呼叫

等價於 invoke()

val sum = {a:Int,b:Int -> a+b}
sum(2,3)
sum.invoke(2,3)
  • Lambda 表示式的簡化

函式引數呼叫時最後一個Lambda可以移出去

函式引數只有一個Lambda,呼叫時小括號可以省略

Lambda只有一個引數可以預設為it

入參、返回值與形參一致的函式可以用函式的引用的方式作為實參傳入

val arr: Array<String> = arrayOf("1","s","sd","rer","54","65")

/*
 * Lambda 表示式 ,傳入it ,並且列印it
 * Lambda只有一個引數可以預設為it
 */
arr.forEach({it -> println(it)})

/*
 * 上面的Lambda 表示式簡化後
 * Lambda只有一個引數可以預設為it
 * 函式引數呼叫時最後一個Lambda可以移出去
 */
arr.forEach(){println(it)}

/*
 * 上面的Lambda 表示式簡化後
 * Lambda只有一個引數可以預設為it
 * 函式引數只有一個Lambda,呼叫時小括號可以省略
 */
arr.forEach{println(it)}

/*
 * 上面的Lambda 表示式簡化後
 * Lambda只有一個引數可以預設為it
 * 入參、返回值與形參一致的函式可以用函式的引用的方式作為實參傳入
 */
arr.forEach(::println) 



/*
 * 判斷陣列中值為rer 是跳出本次迴圈,繼續下次迴圈,相當於continue
 */
 
 arr.forEach [email protected]{
     if(it == "rer") [email protected]
     println(it)
 }
 
 /*
 * 判斷陣列中值為rer 是跳出迴圈,不再進行下面的迴圈,繼續製作該迴圈後面的程式碼
 */
 run [email protected] {
     arr.forEach {
        if(it == "rer") [email protected]
        println(it)
    }}

3. 類成員

  • 屬性:或者說成員變數,類範圍內的變數
  • 方法:或者說成員函式,類範圍內的函式

函式和方法的區別:

函式強調功能本身,不考慮從屬

方法的稱呼通常是從類的角度出發

只是叫法不同而已

  • 定義屬性

構造方法引數中val/var 修飾的都是屬性

類內部也可以定義屬性

class Hello(val aFiled:Int,notAField:Int){
    var anotherField:Float = 3f
}
  • 屬性訪問控制

屬性可以定義getter/setter

val a: Int=0
    get()=field
    
var b: Float = 0f
    get(){
        return field / 3;
    }
    set(value){field = value}
  • 屬性初始化

屬性的初始化儘量在構造方法中完成

無法在構造方法中初始化,嘗試降級為區域性變數

var 用 lateinit 延遲初始化,val 用 lazy 延遲初始化

可空型別謹慎用 null 直接初始化

4. 運算子( ±*/%^? )

官網定義

Expression Translated to
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc() + see below
a– a.dec() + see below
a+b a.plus(b)
a-b a.minus(b)
a*b a.times(b)
a/b a.div(b)
a%b a.rem(b),a.mod(b)(deprecated)
a…b a.rangeTo(b)
a in b b.contains(a)
a !in b !b.contains(a)
a[i] a.get(i)
a[i,j] a.get(i,j)
a[i_1,…,i_n] a.get(i_1,…,i_n)
a[i] = b a.set(i,b)
a[i,j] = b a.set(i,j,b)
a[i_1,…,i_n] =b a.set(i_1,…,i_n,b)
a() a.invoke()
a(i) a.invoke(i)
a(i,j) a.invoke(i,j)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)
  • 基本運算子

任何類可以定義或者過載父類的基本運算子

通過運算子對應的具名函式來定義

對引數的個數做要求,對引數和返回值型別不做要求

不能像 Scala 一樣定義人與運算子

/*
 * 定義一個複數,實部與實部相加,虛部與虛部相加
 */
class Complex(var real: Double,var imaginary: Double){
    operator fun plus(other: Complex):Complex{
        return Complex(real+other.real,imaginary + other.imaginary)
    }
    override fun toString():String{
        return "$real + ${imaginary}i"
    }
}


fun main(args: Array<String>){
    val c1 = Complex(3.0,4.0)//3.0+4.0i
    val c2 = Cpmplex(2.0,7.5)//2.0+7.5i
    println(c1 + c2)
}
  • 中綴表示式

只有一個引數,且用infix 修飾的函式

class Book {
    infix fun on(place:String){...}
}

Book() on "My Desk"
  • 分支表示式

** if 表示式
if … else

if(a == b) ... else if(a == c) ... else ...

表示式與完備性

val x = if(b<0) 0 else b

val x = if(b<0)0 //錯誤,賦值時,分支必須完備

** when 表示式

加強版的 switch ,支援任意型別

支援純表示式條件分支(類似if)

表示式與完備性特性

  • 迴圈語句

基本寫法:
for(element in elements) …

給任意類實現 Iterator 方法

val arr: Array<String> = arrayOf("1","s","sd","rer","54","65")

for(a in arr){
    println(a)
}


for((index,value) in arr.withIndex()){
    println("$index -> $value")
}

for(indexedValue in arr.withIndex()){
    println("${indexedValue.index} -> ${indexedValue.value}")
}


class MyIterator(val iterator: Iterator<Int>){
    operator fun next():Int{
        return iterator.next
    }
    
     operator fun hasNext():Boolean{
        return iterator.hasNext()
    }
}

cal MyIntList{
    private val list = ArrayList<Int>()
    
    fun add(int: Int){
        list.add(int)
    }
    
    fun remove(int: Int){
        list.remove(int)
    }
    
    operator fun iterator():MyIterator{
        return MyIterator(list.iterator())
    }
}


fun main(args: Array<String>){
    val list = MyIntList()
    list.add(1)
    list.add(2)
    list.add(3)
    
    for(i in list){
        println(i)
    }
  
}

/******** while *************/
var x=5
while(x>0){
    println(x)
    x--
}


do{
   println(x)
    x-- 
}while(x>0)

** 跳出或跳過迴圈

跳出,終止迴圈 break

跳過當前迴圈 continue

多層迴圈巢狀的終止結合標籤使用

[email protected](...){
    [email protected](i<0){
        if(...) [email protected]
    }
}

5. 異常捕獲

使用 try{}catch(e: Exception){} 進行異常捕獲

try{  
    //程式正常執行
}catch(e: Exception){
    //程式出現異常,可根據異常型別捕獲相應的異常
}finally{
    //無論執行成功還是出現異常都會執行
}

6. 具名引數

給函式的實參附上形參

fun sum(arg1:Int,arg2:Int) = arg1 + arg2

sun(arg2=3,arg1=2)

7. 變長引數

使用 vararg 修飾

某個引數可以接受多個值

可以不為最後一個引數

如果傳參是由歧義,需要使用具名引數

8. Spread Operator

使用 * 來展開

只支援展開Array

只用於變長列表的實參

val arr=intArrayOf(1,2,3,4,5)

fun printMethod(vararg arrs:Int){
    arrs.forEach(::println)
}

printMethod(*arr)

9.預設引數

為函式引數指定預設值

可以為任意位置的引數指定預設值

傳參時,如果有歧義,需要使用具名引數

val arr=intArrayOf(1,2,3,4,5)

fun printMethod(name:String = "admin",vararg arrs:Int){
    arrs.forEach(::println)
}

printMethod(arrs=*arr)

10. 匯出可執行程式

  • 在build.gradle 中增加
apply plugin: 'application'
mainClassName = ""//程式入口類路徑,Kotlin檔名後加 Kt
  • gradle 重新整理/同步
  • gradle 中的distribution 中點選installDist得到可執行的檔案
  • 在專案目錄下的build資料夾下的install資料夾下
//命令列輸入:
# cd build/install/[專案名稱]
# chmod 755 bin/[專案名稱]
# bin/[專案名稱]

下一篇:(二)Kotlin 面向物件