Kotlin——程序结构(3)

1、常量与变量(var,val)

var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量。这种声明变量的方式和java中声明变量的方式一样。
val是一个只读变量,这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化,因为以后不能被改变。
什么是常量?
val = value,值类型
类似Java的final
不能重复赋值
举例:

运行时常量:val x = getX()
编译期常量:const val x = 2 会提高执行效率

什么是变量?
var = variable
举例:

var x = "HelloWorld"//定义变量
x = "HiWorld"//再次赋值

类型推导
编译器可以推导量的类型

val string = "Hello" //推导出String类型
val int = 5 //Int类型
val x = getString() + 5//String类型

2、函数(function)

什么是函数?
以特定功能组织起来的代码块

fun函数名:[返回值类型]{[函数体]}
fun函数名 = [表达式] //返回值是Unit(相当于java中的void),可不写

匿名函数

fun([参数列表])...

举例:

val say = fun(name:String) = println("Hello")

3、lambda表达式

实际上就是匿名函数
写法{[参数列表]->[函数体,最后一行是返回值]}
举例:

val sum = {a:Int,b:Int->a+b}
返回的是a+b的和

类型表示举例
1、()->Unit无参,返回值为Unit
2、(Int)->Int传入整型,返回一个整型
3、(String,(String)->String)->Boolean传入字符串、Lambda表达式,返回Boolan

Lambda表达式的调用
1、用()进行调用
2、等价于invoke()
举例

val sum = {a:Int,b:Int->a+b}
sum(2,3)
sum.invoke(2,3)

Lambda表达式的简化
1、如果函数调用时,最后一个是lambda表达式,在传参的时候可以将它移出去
2、函数参数只有一个lambda表达式,调用时小括号可省略
3、lambda表达式只有一个参数,不写也可以,名字默认为it
4、实参、返回值与形参一致的函数可以用方式作为实参传入

4、类成员(成员方法、成员变量)

属性
或者说成员变量,类范围内的变量
方法
或者说成员函数,类范围内的函数
函数和方法的区别
1、函数强调功能本身,不考虑从属
2、方法的称呼通常是丛类的角度出发
3、叫法不同
定义方法
写法与普通函数完全一致
定义属性
1、构造方法参数中var/val修饰的都是属性
2、类内部也可以定义属性

class Hello(val aField:Int,notAFlield:Int){
var anotherField:Float = 3f
}
aField 是属性
notAField 不是属性,只是普通构造方法的参数

属性的访问控制
属性可以定义getter/setter
举例:

var a: Int = 0
get() = field
set(value) {
field = value
}
val b:Float = 0f
//set(value){ field =value}
get() = field

Kotlin——程序结构(3)_第1张图片
val不可以set().png

属性初始化
1、属性的初始化尽量在构造方法中完成
2、无法在构造方法中初始化,尝试降级为局部变量
3、var用lateinit延迟初始化,val用lazy
4、可空类型谨慎用null直接初始化(不建议使用null初始化)

class LazyTest {
var a: Int = 0;
lateinit var str: String
lateinit var x1: X
val STR: String = "STR"
val x2: X by lazy {
print("lazy X")
X()
}
}

class X

fun main(args: Array) {
val e: LazyTest = LazyTest()
e.x2
}

5、基本运算符

1、任何类都可以定义或重载父类的基本运算符
2、通过运算符对应的具名函数来定义
3、对参数的个数要求,对参数和返回值类型不做要求
4、不能像Scala一样定义任意运算符

6、表达式(中缀表达式、分支表达式、when表达式等)

1、中缀表达式
只有一个参数,且用infix修饰的函数

fun main(args: Array) {
    val b = Book();
    b on "哈哈"
}
class Book {
    infix fun on(str: String) {
        print("Book on $str")
    }
}

运行结果:Book on 哈哈

2、分支表达式
1)if...else

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

2)表达式与完备性

val x = if(b<0) 0 else b
val x = if(b<0) 0 //错误,赋值时,分支必须完备

3、when表达式
1)加强版switch,支持任意类型,不需些break
2)支持纯表达式条件分支(类似if)
3)表达式与完备性
举例:

fun main(args: Array) {
    val x = 5
    when (x) {
        is Int -> println("整型")
        in 0..10 -> println(" x in 0..10")
        in 0..100 -> println(" x in 0..100")

        5 -> println("x:$x 值是5")
    }

    val a = when{
        x in 0..10 ->100
        else ->0
    }
    print("a的值是$a")
}

结果:


when事例结果.png

7、循环语句(for循环、while循环、continue、break)

1)for循环
a.基本写法

for(element in elements)...

b.给任意类实现Iterator方法
运行机制简单举例:

class MyIterator(val iterator:Iterator){

    operator fun next():Int{
        return iterator.next()
    }

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

}

class MyIntList{
    private val list = ArrayList()

    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) {
    val list = MyIntList()
    list.add(1)
    list.add(2) 
    list.add(3)

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

2)while循环
a. do...while(...)...
b. while(...)...
3)continue
跳过当前循环
4)break
终止循环
多层循环嵌套的终止结合标签使用

Outter@for(...){
Inner@while(i<0){if(...break@Outter)}
}
如果break后面没有@Outter,是把while给break了,会继续执行for循环,如果加了@Outter了,就是for循环给break了

8、异常捕获(try...catch、finally)

try...catch
1、catch分支匹配异常类型
2、表达式,可以用来赋值,与if..else、when类似
例如:

fun main(args: Array) {

    val a = try {
        0 / 3
    } catch (e: Exception) {
        e.printStackTrace()
        println("出现异常")
        0
    } finally {
        println("执行finally")
    }
    println(a)
}

运行结果:

执行finally
3

finally
无论代码是否抛出异常都会执行

return try(x/y)catch(e:Exception){0}finally{...}
如果抛异常返回0,否则返回x/y,finally一定会执行,先执行finally再返回。

9、具名参数,变长参数、默认参数

1)具名参数
给函数的实参附上形参
举例:

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

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

Spread Opreator
a.只支持展开的Array
b.只用于变长参数列表的实参
c.不能重载

3)默认参数
a.为函数参数指定默认值
b.可以为任意位置的参数指定默认值
c.传参时,如果有歧义,需要使用具名参数

10.练习

1)简单实现计算器

fun main(args: Array) {

    while (ok()) {
        try {
            println("请输入,例如:3 + 4")
            val input = readLine() ?: break
            val split = input.trim().split(" ")
            if (split.size < 3) {
                throw IllegalArgumentException("参数个数不对")
            }
            val a = split[0].toDouble()
            val op = split[1]
            val b = split[2].toDouble()
            println("$a $op $b -> ${Opreator(op).apply(a, b)}")
        } 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
        }
    }
    println("退出成功!")
}

fun ok(): Boolean {
    return true
}

你可能感兴趣的:(Kotlin——程序结构(3))