Kotlin中的程序结构详解

作者: Android架构 | 来源:发表于2019-03-05 21:22 被阅读7次

    目录

    • val,var关键字
    • 函数
    • Lambda表达式
    • 类成员
    • 运算符
    • 表达式
    • 循环语句(for循环,while循环,continue,break)
    • 异常捕获
    • 具名参数,变长参数,默认参数

    val,var关键字

    kotlin中关键字val用来表示常量,var用来表示变量

    val a : String = "Hello world"
    var b : String = "Hello world"
    
    

    a的值不能改变,b的值可以改变
    另外,kotlin中有类型推导的功能,可以不用写String类型例如下面这样

    val c = "Hello world"
    
    

    可以推倒出c是String类型.
    kotlin中的val和java中的final有什么区别?
    java中的final是编译期常量,什么是编译期常量?就是在编译的时候就把引用换成值。而kotlin中的val修饰的只是一个不能改变值的变量(可以通过反射改变),如果我们想要在kotlin中定义编译期常量我们可以加上const关键字.

    函数

    kotlin中函数定义

    fun main(args: Array<String>) : Unit{
    
    }
    
    

    Unit是返回类型,它相当于java中的Void关键字声明

    fun sum(arg1 : Int,arg2: Int) : Int{
        return arg1 + arg2
    }
    
    

    当然也是可以返回其它的类型

    fun main(args: Array<String>) : Unit{
        val arg1 = args[0].toInt()
        val arg2 = args[1].toInt()
        println("$arg1 + $arg2 = ${sum(arg1,arg2)}")
    }
    
    

    对于返回值只有一个表达式的函数还可以简写成:

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

    匿名函数

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

    类成员

    如何在kotlin中声明一个类

    class MM(name : String,age : Int,voice : String){
        fun sing(name : String){
            println("sing $name")
        }
    }
    
    

    声明及使用

    fun main(args: Array<String>) {
        val mm = MM("",22,"未知")
        mm.sing("天鹅湖")
    }
    
    

    在java中声明一个成员变量,通常会有set和get方法如下

    public class JavaA {
        private int b = 0;
    
        public int getB() {
            System.out.println("some one tries to get b.");
            return b;
        }
    
        public void setB(int b) {
            System.out.println("some one tries to set b.");
            this.b = b;
        }
    }
    
    

    但是在kotlin中默认是不需要set和get方法的

    open class A{
        var b = 0
    }
    
    

    直接就可以使用

    var a : A = A()
    a.b
    
    

    这和java中声明成员变量为public差不多. 其实也是可以设置get/set方法的,如下

    open class A{
        var b = 0
            get() = field
            set(value){ field = value}
    }
    
    

    另外,kotlin中存在一种延迟加载的机制,var可以用lateinit关键字,val可以用lazy关键字.

    open class A{
        var b = 0
        lateinit var a : String
        lateinit var d : X
        val e : X by lazy{
            println("init X")
            X()
        }
    }
    
    

    运算符

    在java当中,运算符都是定死的,+-*/, 1+1一定等于2,但是在kotlin中运算符是可以自定义的,也就是说1+1可以不等于2.
    官网详情:https://kotlinlang.org/docs/reference/operator-overloading.html
    下面我们自定义加法运算符,做一个复数相加的运算

    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}"
        }
    }
    
    
    fun main(args: Array<String>) {
        val c1 : Complex = Complex(3.0,4.0);
        val c2 : Complex = Complex(4.0,5.0);
        println(c1 + c2)
    }
    
    

    最终输出

    7.0+9.0i
    
    

    运算符重写只对参数个数做要求,对参数和返回值类型不做要求
    例如我可以重写plus如下:

    operator fun plus(other:Int) : Complex{
        return Complex(real+other,imaginary+other)
    }
    
    
    operator fun plus(other:Int) : Int{
       return other
    }
    
    

    以上都是可以的, 另外我们再来看看infix中缀表达式

    if ("-name" in args){        
    }
    
    

    使用in其实是关联到了Array中的contains函数,他返回是否存在该元素

    public operator fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.contains(element: T): Boolean {
        return indexOf(element) >= 0
    }
    
    

    我们也可以使用infix定义其它的运算符号如 on.

    class Desk
    
    class Book{
        infix fun on(desk: Desk):Boolean{
            return false
        }
    }
    
    fun main(args: Array<String>) {
        val d = Desk()
        val b = Book()
        if (b on d){
    
        }
    }
    
    

    表达式

    if表达式可以有返回值

    class Kotlin{
        val DEBUG = 1
        val USER = 2
        fun test(){
            var rule = true
            var mode = if (rule){
                DEBUG
            }else{
                USER
            }
        }
    }
    
    

    when表达式
    java中的swich表达式针对的类型有限(只能和int类型兼容,1.7增加了String和枚举),在kotlin中使用when来替代swich表达式

    fun test(){
            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")
            }
        }
    
    

    同时when也是有返回值的

    fun test(){
        val a = A()
           var mode = when {
            a == null -> 1 else ->0
        }
    }
    
    

    循环语句(for循环,while循环,continue,break)

    for循环的几种基本形式

    val array = intArrayOf(1, 2, 3)
            for (arg in array){
                println(arg)
            }
    
    
    for ((index,value) in array.withIndex()){
           println("$index -> $value")
    }
    
    
    for (indexValue in array.withIndex()){
          println("${indexValue.index} -> ${indexValue.value}")
    }
    
    

    关于in操作符

    可以看出in操作符的对象必须满足实现以上三个方法,下面我们来自定义迭代类,然后使用in进行迭代输出

    class MyIterator(val iterator: Iterator<Int>){
            operator fun next(): Int{
                return iterator.next()
            }
            operator fun hasNext(): Boolean{
                return iterator.hasNext();
            }
        }
    
    
    class MyIniList{
            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())
            }
        }
    
    

    最终输出

     val list = MyIniList()
            list.add(1)
            list.add(2)
            list.add(3)
            for (arg in list){
                println(arg)
            }
    
    

    while语句

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

    continue,break

    class Loop2{
    
        class Student{
            fun isNotClothedProperly():Boolean{
                return false
            }
        }
    
        fun test(){
            val students = ArrayList<Student>()
            val you = Student()
            for (student in students){
                if (student == you) continue
                if (student.isNotClothedProperly()){
                    break
                }
            }
        }
    }
    
    

    异常捕获

    class Sum{
        fun input(args :Array<String>){
            try {
                val arg1 = args[0].toInt()
                val arg2 = args[1].toInt()
                println("$arg1+$arg2=${arg1+arg2}")
            }catch (e : NumberFormatException){
                println("您确定输入的是整数吗?")
            }catch (e : ArrayIndexOutOfBoundsException){
                println("您确定输入的是两个整数吗?")
            }catch (e : Exception){
                println("程序出现了未知异常.${e.message}")
            }finally {
                println("谢谢使用")
            }
        }
    }
    
    

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

    具名参数
    具名参数的意思是,在传入参数的同时给定参数名字

    class Test{
        fun test(){
            sum(arg2 = 3,arg1 = 2)
        }
        fun sum(arg1 : Int, arg2 : Int){
    
        }
    }
    
    

    变长参数
    参数的个数可以任意改变

    class Test{
    
        fun test(){
            hello(1,2,3,4,5,string = "hello")
        }
    
        fun hello(vararg ints : Int, string: String){
            ints.forEach(::println)
        }
    }
    
    

    变长参数还支持一个特性

    fun test(){
         val array = intArrayOf(1,3,4,5)
         hello(*array,string = "hello")
    }
    
    

    *表示把数组展开成一个个元素传进去.

    默认参数
    默认参数参数可以给参数设定一个默认值,调用函数的时候可以不用传该参数,具体使用如下

    class Test{
        fun test(){
            val array = intArrayOf(1,3,4,5)
            hello(ints = *array,string = "hello")
        }
    
        fun hello(double: Double = 3.0,vararg ints : Int, string: String){
            ints.forEach(::println)
        }
    }
    
    

    以上是我对kotlin中程序结构相关内容的总结.

    最后

    在这里我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案做成了文档和架构视频资料免费分享给大家【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

    资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

    点击链接加入群聊【Android移动架构总群】:加入群聊

    资料大全

    相关文章

      网友评论

        本文标题:Kotlin中的程序结构详解

        本文链接:https://www.haomeiwen.com/subject/forauqtx.html