zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Kotlin 程序结构

Kotlin 程序结构
2023-09-14 09:14:22 时间

常量
val = value,值类型
类似Java的final
不可能重复赋值

  • 运行时常量:val x =getX()

  • 编译期常量:const val x = 2
    变量
    val = variable

  • var x = “HelloWorld”//定义变量

  • x = “Hello,China”//再次赋值
    类型推导
    编译器可以推导量的类型

  • val string =“Hello” //推导出String类型

  • val int = 5 //Int 类型

  • var x = getString() + 5 //String类型
    函数
    以特定功能组织起来的代码块

  • fun函数名:[返回值类型]{[函数体]}

  • fun函数名 = [表达式]
    举例:

  • fun sayHi(name:String) { println(“Hi,$name”) }

  • fun sayHi(name:String) = println(“Hi,$name”)
    匿名函数
    fun([参数列表])…

  • val sayHi = fun(name:String) = println(“Hi,$name”)
    编写函数的注意事项
    功能单一
    函数名要做到顾名思议
    参数个数不要太多
    Lambda 表达式
    匿名函数
    写法:{[参数列表]->[函数体,最后一行是返回值]}

  • val sum = {a:Int,b:Int->a + b }
    Lambda的类型举例
    ()->Unit
    无参,返回值为Unit
    (Int)->Int
    传入整型,返回一个整型
    (String,(String)->String)->Boolean

  • 传入字符串、Lambda表达式,返回Boolean
    Lambda表达式的调用
    用()进行调用
    等价于invoke()

  • val sum = {a:Int,b:Int -> a + b}

  • sum(2,3)

  • sum.invoke(2,3)
    Lambda表达式的简化
    函数参数调用时最后一个Lambda可以移出去
    函数参数只有一个Lambda,调用时小括号可以省略
    Lambda只有一个参数可默认为it
    入参,返回值与形参一致的函数可以用函数引用的方式作为实参传入

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

类成员
属性:作者说成员变量,类范围内的变量
方法:或者说成员函数,类范围内的函数
函数和方法的区别
函数强调功能本身,不考虑从属
方法的称呼通常是从类的角度出发
叫法不同而已,不要纠结
定义属性
构造方法参数中val/var修饰的都是属性
类内部也可以定义属性
属性访问控制
属性可以定义getter/setter

  • val a:Int = 0 //不能定义set()
  • get() = field
  • var b:Float = 0f //可以定义getter/setter
  • set(value){field = value}
    属性初始化
    属性的初始化尽量在构造方法中完成
    无法在构造方法中初始化,尝试降级为局部变量
    var用lateinit延迟初始化,val用lazy
    可空类型谨慎用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()
    }
    //可空类型谨慎用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

基本运算符
任何类可以定义或者重载父类的基本运算符
通过运算符对应的具体函数来定义
对参数个数作要求,对参数和返回值类型不作要求
不能像Scale一样定义任意运算符
中缀表达式
只有一个参数,且用infix修饰的函数

- class Book{ infix fun on(place:String){...}}
- Book() on "My Desk"
分支表达式
if...else
- if(a ==b ) ... else if(a == c) ... else ...
表达式与完备性
- val x = if(b < 0) 0 else b
- val x = if(b < 0) 0 //错误,赋值时,分支必须完备
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. 表达式给变量赋值
    val mode = if (args.isNotEmpty() && args[0] == "1") {
        DEBUG
    } else {
        USER
    }

    println("请输入用户名:")
    val username = readLine()
    println("请输入密码:")
    val password = readLine()

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

        println("管理员登录成功")
    } else if (username == USERNAME && password == PASSWORD) {
        println("登录成功")
    } else {
        println("登录失败")
    }

When 表达式
加强版switch,支持任意类型
支持纯表达式条件分支(类似if)
表达式与完备性

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

循环语句
for循环
基本写法

  • for(element in elements)…
    给任意类实现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循环
类似于C语言

跳过和终止循环
跳过当前循环用continue
终止循环用break
多层循环嵌套的终止结合便签使用

- Outter@for(...){
     Inner@while(i < 0){ if(...) break } //结束while循环
      Inner@while(i < 0){ if(...) break@Outter }//结束外层for循环
}

具名参数
给函数的时参附上形参
举例:

- fun sum(arg1:Int,arg2:Int) = arg1 + arg2
- sum(arg1 = 2, arg2 = 3)

变长参数
某个参数可以接收多个值
可以不为最后一个参数
如果传参时有歧义,需要使用具名参数

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

本章知识点示例

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

            println("请输入算式例如:3 + 4")
            val input = readLine() ?: break
            if (input != null) {
                val splits = input.trim().split(" ")
                if (splits.size < 3) {
                    throw IllegalArgumentException("参数个数不对")
                }
                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("您输入的数字格式不对")
        } catch (e: IllegalArgumentException) {
            println("请输入用空格分隔的三个参数")
        } catch (e:Exception){
            println("未知异常:${e.message}")
        }
        println("再来一发?[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)
    }
}
请输入算式例如:3 + 4
566.33.33 + 1
您输入的数字格式不对
再来一发?[Y]
y
请输入算式例如:3 + 4
23+1
请输入用空格分隔的三个参数
再来一发?[Y]
y
请输入算式例如:3 + 4
5 + 6 
5.0 + 6.0 = 11.0
再来一发?[Y]