Kotlin 進(jìn)階之路8 程序結(jié)構(gòu)

Kotlin 進(jìn)階之路 目錄

常量

  • val = value,值類型
  • 類似Java的final
  • 不可能重復(fù)賦值
- 運(yùn)行時(shí)常量:val x =getX()
- 編譯期常量:const val x = 2

變量

  • val = variable
- var x = "HelloWorld"http://定義變量
- x = "Hello,China"http://再次賦值

類型推導(dǎo)

  • 編譯器可以推導(dǎo)量的類型
- val string ="Hello" //推導(dǎo)出String類型
- val int = 5 //Int 類型
- var x = getString() + 5 //String類型 

函數(shù)

  • 以特定功能組織起來(lái)的代碼塊
- fun[函數(shù)名]([參數(shù)列表]):[返回值類型]{[函數(shù)體]}
- fun[函數(shù)名]([參數(shù)列表]) = [表達(dá)式]

舉例:

- fun sayHi(name:String) { println("Hi,$name") }
- fun sayHi(name:String) = println("Hi,$name")

匿名函數(shù)

  • fun([參數(shù)列表])...
- val sayHi = fun(name:String) = println("Hi,$name")

編寫函數(shù)的注意事項(xiàng)

  • 功能單一
  • 函數(shù)名要做到顧名思議
  • 參數(shù)個(gè)數(shù)不要太多

Lambda 表達(dá)式

  • 匿名函數(shù)
  • 寫法:{[參數(shù)列表]->[函數(shù)體,最后一行是返回值]}
- val sum = {a:Int,b:Int->a + b }
Lambda的類型舉例
  • ()->Unit
無(wú)參,返回值為Unit
  • (Int)->Int
傳入整型,返回一個(gè)整型
  • (String,(String)->String)->Boolean
- 傳入字符串、Lambda表達(dá)式,返回Boolean
Lambda表達(dá)式的調(diào)用
  • 用()進(jìn)行調(diào)用
  • 等價(jià)于invoke()
- val sum = {a:Int,b:Int -> a + b}
- sum(2,3)
- sum.invoke(2,3)
Lambda表達(dá)式的簡(jiǎn)化
  • 函數(shù)參數(shù)調(diào)用時(shí)最后一個(gè)Lambda可以移出去
  • 函數(shù)參數(shù)只有一個(gè)Lambda,調(diào)用時(shí)小括號(hào)可以省略
  • Lambda只有一個(gè)參數(shù)可默認(rèn)為it
  • 入?yún)ⅲ祷刂蹬c形參一致的函數(shù)可以用函數(shù)引用的方式作為實(shí)參傳入
fun main(args: Array<String>) {

    println(int2Long(3))
    println(sum(2, 3))
    println(sum2(5, 6))
    println(sum.invoke(1, 3))

    val args: Array<Int> = arrayOf(1, 2, 3, 4, 5, 6)
    for (i in args) {
        println(i)
    }
    args.forEach(::println)
    println("--------------------------------")
    args.forEach ForEach@{
        if (it == 2) return@ForEach
        println(it)
    }
    println("The End 1.....")
    args.forEach {
        if (it == 3) return
        println(it)
    }
    println("The End 2.....")
}

val int2Long = fun(x: Int): Long {
    return x.toLong()
}

val sum = { arg1: Int, arg2: Int -> arg1 + arg2 }

val sum2 = { arg1: Int, arg2: Int -> println("$arg1 + $arg2 = ${arg1 + arg2}") }
3
5
5 + 6 = 11
kotlin.Unit
4
1
2
3
4
5
6
1
2
3
4
5
6
--------------------------------
1
3
4
5
6
The End 1.....
1
2

類成員

  • 屬性:作者說(shuō)成員變量,類范圍內(nèi)的變量
  • 方法:或者說(shuō)成員函數(shù),類范圍內(nèi)的函數(shù)

函數(shù)和方法的區(qū)別

  • 函數(shù)強(qiáng)調(diào)功能本身,不考慮從屬
  • 方法的稱呼通常是從類的角度出發(fā)
  • 叫法不同而已,不要糾結(jié)

定義屬性

  • 構(gòu)造方法參數(shù)中val/var修飾的都是屬性
  • 類內(nèi)部也可以定義屬性

屬性訪問(wèn)控制

  • 屬性可以定義getter/setter
- val a:Int = 0 //不能定義set()
- get() = field
- var b:Float = 0f //可以定義getter/setter
- set(value){field = value}

屬性初始化

  • 屬性的初始化盡量在構(gòu)造方法中完成
  • 無(wú)法在構(gòu)造方法中初始化,嘗試降級(jí)為局部變量
  • var用lateinit延遲初始化,val用lazy
  • 可空類型謹(jǐn)慎用null直接初始化
class X
//lateinit 延遲初始化
class A {
    var b = 0
    lateinit var c: String
    lateinit var d: X
    val e: X by lazy {
        println("init X")
        X()
    }
    //可空類型謹(jǐn)慎用null直接初始化
    var cc: String? = null
}

fun main(args: Array<String>) {
    println("start")
    val a = A()
    println("init a")
    println(a.b)
    println(a.e)

    a.d = X()
    println(a.d)

    println(a.cc?.length)
}
start
init a
0
init X
chapter3.X@7106e68e
chapter3.X@7eda2dbb
null

基本運(yùn)算符

  • 任何類可以定義或者重載父類的基本運(yùn)算符
  • 通過(guò)運(yùn)算符對(duì)應(yīng)的具體函數(shù)來(lái)定義
  • 對(duì)參數(shù)個(gè)數(shù)作要求,對(duì)參數(shù)和返回值類型不作要求
  • 不能像Scale一樣定義任意運(yùn)算符

中綴表達(dá)式

  • 只有一個(gè)參數(shù),且用infix修飾的函數(shù)
- class Book{ infix fun on(place:String){...}}
- Book() on "My Desk"

分支表達(dá)式

  • if...else
- if(a ==b ) ... else if(a == c) ... else ...
  • 表達(dá)式與完備性
- val x = if(b < 0) 0 else b
- val x = if(b < 0) 0 //錯(cuò)誤,賦值時(shí),分支必須完備
private const val USERNAME = "kotlin"
private const val PASSWORD = "jetbrains"

private const val ADMIN_USER = "admin"
private const val ADMIN_PASSWORD = "admin"

private const val DEBUG = 1
private const val USER = 0

fun main(args: Array<String>) {

    //1.變量賦值
//    var mode = USER
//    if (args.isNotEmpty() && args[0] == "1") {
//        mode = DEBUG
//    }
//2. 表達(dá)式給變量賦值
    val mode = if (args.isNotEmpty() && args[0] == "1") {
        DEBUG
    } else {
        USER
    }

    println("請(qǐng)輸入用戶名:")
    val username = readLine()
    println("請(qǐng)輸入密碼:")
    val password = readLine()

    if (mode == DEBUG && username == ADMIN_USER && password == ADMIN_PASSWORD) {

        println("管理員登錄成功")
    } else if (username == USERNAME && password == PASSWORD) {
        println("登錄成功")
    } else {
        println("登錄失敗")
    }

When 表達(dá)式

  • 加強(qiáng)版switch,支持任意類型
  • 支持純表達(dá)式條件分支(類似if)
  • 表達(dá)式與完備性
fun main(args: Array<String>) {
    val x = 5
    when (x) {
        is Int -> println("Hello $x")
        in 1..100 -> println("$x is in 1..100")
        !in 1..100 -> println("$x is not in 1..100")
        args[0].toInt() -> println("$x == args[0]")
    }
}
Hello 5

循環(huán)語(yǔ)句

for循環(huán)
  • 基本寫法
- for(element in elements)...
  • 給任意類實(shí)現(xiàn)Iterator方法
fun main(args: Array<String>) {

    val args: Array<Char> = arrayOf('a', 'b', 'c', 'd')
    for (arg in args) {
        println(arg)
    }
    println("-------------------------------")
    for ((index, value) in args.withIndex()) {
        println("$index -> $value")
    }
    println("-------------------------------")
    for (indexedValue in args.withIndex()) {
        println("${indexedValue.index} -> ${indexedValue.value}")
    }
    println("-------------------------------")
    val list = MyIntList()
    list.add(1)
    list.add(2)
    list.add(3)

    for (i in list) {
        println(i)
    }
}

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

    operator fun hasNext(): Boolean {
        return iterator.hasNext()
    }
}

class 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())
    }
}
a
b
c
d
-------------------------------
0 -> a
1 -> b
2 -> c
3 -> d
-------------------------------
0 -> a
1 -> b
2 -> c
3 -> d
-------------------------------
1
2
3
While循環(huán)

類似于C語(yǔ)言

跳過(guò)和終止循環(huán)
  • 跳過(guò)當(dāng)前循環(huán)用continue
  • 終止循環(huán)用break
  • 多層循環(huán)嵌套的終止結(jié)合便簽使用
- Outter@for(...){
     Inner@while(i < 0){ if(...) break } //結(jié)束while循環(huán)
      Inner@while(i < 0){ if(...) break@Outter }//結(jié)束外層for循環(huán)
}

具名參數(shù)

  • 給函數(shù)的時(shí)參附上形參
  • 舉例:
- fun sum(arg1:Int,arg2:Int) = arg1 + arg2
- sum(arg1 = 2, arg2 = 3)

變長(zhǎng)參數(shù)

  • 某個(gè)參數(shù)可以接收多個(gè)值
  • 可以不為最后一個(gè)參數(shù)
  • 如果傳參時(shí)有歧義,需要使用具名參數(shù)
fun main(vararg args: String) {
//    for (arg in args) {
//        println(arg)
//    }
    hello(18.0,1,2,3,4,string ="Hello")

    val array = intArrayOf(5,4,3,2,1)
    hello(18.0,*array,string ="Hello")
}

fun hello(double: Double,vararg ints: Int, string: String) {
    ints.forEach(::println)
}
1
2
3
4
5
4
3
2
1

本章知識(shí)點(diǎn)示例

fun main(args: Array<String>) {
    while (true) {
        try {

            println("請(qǐng)輸入算式例如:3 + 4")
            val input = readLine() ?: break
            if (input != null) {
                val splits = input.trim().split(" ")
                if (splits.size < 3) {
                    throw IllegalArgumentException("參數(shù)個(gè)數(shù)不對(duì)")
                }
                val arg1 = splits[0].toDouble()
                val op = splits[1]
                val arg2 = splits[2].toDouble()
                println("$arg1 $op $arg2 = ${Operator(op).apply(arg1, arg2)}")


            }
        } catch (e: NumberFormatException) {
            println("您輸入的數(shù)字格式不對(duì)")
        } catch (e: IllegalArgumentException) {
            println("請(qǐng)輸入用空格分隔的三個(gè)參數(shù)")
        } catch (e:Exception){
            println("未知異常:${e.message}")
        }
        println("再來(lái)一發(fā)?[Y]")
        val cmd = readLine()
        if (cmd == null || cmd.toLowerCase() != "y") {
            break
        }
    }

}

class Operator(op: String) {
    val opFun: (left: Double, right: Double) -> Double

    init {
        opFun = when (op) {
            "+" -> { l, r -> l + r }
            "-" -> { l, r -> l - r }
            "*" -> { l, r -> l * r }
            "/" -> { l, r -> l / r }
            "%" -> { l, r -> l % r }
            else -> {
                throw UnsupportedOperationException(op)
            }
        }

    }

    fun apply(left: Double, right: Double): Double {
        return opFun(left, right)
    }
}
請(qǐng)輸入算式例如:3 + 4
566.33.33 + 1
您輸入的數(shù)字格式不對(duì)
再來(lái)一發(fā)?[Y]
y
請(qǐng)輸入算式例如:3 + 4
23+1
請(qǐng)輸入用空格分隔的三個(gè)參數(shù)
再來(lái)一發(fā)?[Y]
y
請(qǐng)輸入算式例如:3 + 4
5 + 6 
5.0 + 6.0 = 11.0
再來(lái)一發(fā)?[Y]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。