美文网首页
Kotlin:变量和函数

Kotlin:变量和函数

作者: jingkaiqaq | 来源:发表于2021-05-25 15:10 被阅读0次
    kotlin&android.png

    前言

    本专栏基于郭霖第一行代码第三版Kotlin知识编写,在此仰慕+感谢大佬,当初就是为了学习Kotlin买的这本书,果然大佬讲东西还是通俗易懂~彩虹屁安排一波🌈
    这个专栏我会将本人学习到的关于Kotlin知识顺序渐进通俗的输出一遍,相信各位大佬看了之后一定会直呼牛批!
    下面有请各位大佬观看通俗易懂Kotlin系列之第一篇文章——变量和函数
    第一篇文章首先了解 变量、 函数、 逻辑控制语句、 面向对象 、lambda、 空指针处理 、内嵌表达式等知识

    1:变量

    1.1:val和var

    val(value)用来声明一个不可变的变量,对应java中的final
    var(variable)用来声明一个可变的变量,对应java中的非final
    在Java中一个良好的编程习惯是:除非一个变量被明确允许被修改否则他都应该被加上final变量
    同样的在kotlin中为了保持代码的健壮性,我们都应该首先使用val来声明一个变量,在没有变法满足需求的时候再使用var

    1.2:Kotlin中的类型推导机制

    fun main() {
        val data = 10
        println("data的值是$data")
    }
    

    我们使用声明data赋值为10 kotlin会自动将data推导为整形变量

    运行之后如我们所料 image.png 但是Koltin中的类型推导并不是总是正常工作,比如我们在对一个变量进行延时赋值的时候Kotlin就无法进行类型推导了

    这时候就应该这样写:

        val data1: Int = 10
        println(data1)
    

    1.3:Java和Kotlin数据类型对照表

    image.png

    2:函数

    2.1:fun(function)是定义函数关键字,无论定义什么函数都需要使用fun来声明

    我们只要掌握以下命名规范就可以掌握80%的编程场景

    fun methodTest(num1: Int, num2: Int): Int {
        return max(num1, num2)
    }
    

    当函数中的代码只有一行代码的时候可以不用编写代码体,直接写在代码后边即可

    fun methodTest(num1: Int, num2: Int): Int = max(num1, num2)
    

    由于Kotlin有出色的类型推到机制 max函数返回必定是Int类型,因此我们可以继续简化代码

    fun methodTest(num1: Int, num2: Int) = max(num1, num2)
    

    3:逻辑控制语句

    程序的执行语句主要分为三种:顺序语句、条件语句、循环语句

    3.1:if条件语句

    if语句kotlin和java没什么太大的区别,下面演示一段条件语句在Kotlin中如何使用和简化

    fun getNum(num1: Int, num2: Int): Int {
        var result = 0
        if (num1 > num2) {
            result = num1
        } else {
            result = num2
        }
        return result
    }
    

    简化

    fun getNum2(num1: Int, num2: Int): Int {
        var result = if (num1 > num2) {
            num1
        } else {
            num2
        }
        return result
    }
    

    再简化

    fun getNum2(num1: Int, num2: Int): Int {
        return if (num1 > num2) {
            num1
        } else {
            num2
        }
    }
    

    我们上边说过代码体中只有一段代码的时候可以不写函数体 直接用=链接即可,另外kotlin有出色类型推导机制这里可以将Int直接省略 如下最终代码为:

    fun getNum2(num1: Int, num2: Int) = if (num1 > num2) {
        num1
    } else {
        num2
    }
    
    

    3.2:when条件语句

    kotlin中的when语句跟java中的switch差不多,但是又比switch强大...

    fun whenTest(name: String) = when (name) {
        "jingkai" -> 88
        "jingxiaokai" -> 100
        else -> 0
    }
    

    或者使用

    fun whenTest2(name: String) = when {
        name == "Tom" -> 82
        name == "Jim" -> 11
        name == "Cha" -> 12
        else -> 0
    }
    

    另外也kotlin中的when也可以用来判断类型:

    fun checkNum(num: Number) = when (num) {
        is Int -> println("是int")
        is Double -> println("是Double")
        else -> println("什么也不是")
    }
    

    is相当于java中的instanceof关键字

    3.3:循环语句

    for-in循环
    区间:
    0..10 代表0到10的闭区间
    0 until 10 代表0到10 的左闭右开区间

    fun forTest() {
        for (i in 0 until 10 step 2) {       
        }
    }
    

    如上代码代表在0到10的区间内每次都增加2,也就是使用step跳过复杂的逻辑
    如果想要实现降序 可以使用 downto关键字

    fun forTest() {
        for (i in 0 downTo 10 step 2) {
        }
    }
    

    4:面向对象编程

    4.1:类与对象

    在kotlin中创建对象

    fun classTest() {
        val data = Data("jingkais", 1)
        data.height="178"
        data.weight="77"
    }
    

    4.2:继承与构造函数

    Kotlin中的继承可以这样写 使用open声明一个类可以被继承 ,:表示 Student继承自Person

    open class Person(val name: String,val age: Int) {
    }
    class Student( name: String,  age: Int) : Person(name, age) {
    }
    

    kotlin将构造函数分为了两种 主构造函数 和 次构造函数
    主构造函数没有函数体直接写类名后边即可 声明和使用如下
    因为在主构造函数中没有函数体 我们可以使用init函数来执行其它逻辑语句

    class Student( name: String,  age: Int) : Person(name, age) {
        init {
            //书写逻辑
        }
    }
    val student = Student("jingkais", 18)
    

    次构造函数:
    kotlin规定当一个类中机有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数
    kotlin次构造函数用constructor关键字来定义的

    class Student(name: String, age: Int) : Person(name, age) {
        init {
            //书写逻辑
        }
        constructor() : this("", 0)
        constructor(height: String, wight: String) : this("", 0)
    }
    

    另一种情况:只有次构造函数没有主构造函数

    class Student : Person {
        constructor(name: String, age: Int) : super(name, age) {
        }
    }
    

    4.3:接口

    kotlin中的接口跟java中的接口没有任何区别

    interface StudyEnglish {
        fun doHomeWork()
        fun readBooks()
    }
    //调用
    class Student : Person("", 1), StudyEnglish {
        override fun doHomeWork() {
            TODO("Not yet implemented")
        }
        override fun readBooks() {
            TODO("Not yet implemented")
        }
    }
    

    4.4:java和kotlin函数可见修饰符对照表

    image.png

    4.5:数据类与单列类

    Kotlin中新建数据类 就是我们平常所说的的bean可以直接新建 包→New→Kotlin File/Class/Data class

    data class Data(val name: String, val age: Int) {
    
    }
    

    并且kotlin会帮你将equals() hashCode() toString() 等固定且无实际意义的的方法自动生成

    单列模式用于避免重复创建对象 减少资源的浪费
    在kotlin中创建单列类十分简单 →New→Kotlin File/Object

    object Singleton {
        fun singleTest() {
            println("单列类")
        }
    }
    

    4.6:Lambda编程

    lambda分为基础知识、高阶函数、DSL等高级Lambda技巧

    4.6.1:集合的创建与遍历

    kotlin提供了内置listof(不可变)mutableListOf(可变)新建一个集合

     val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
     val list = mutableListOf("Apple", "Banana", "Orange", "Pear", "Grape")
    

    set不可以存放重复的数据,同样set也存在 mutableSetOf(可变)

    val set = setOf("Apple", "Banana", "Orange", "Pear", "Grape")
    

    map集合,同样map也存在 mutableMapOf(可变)

    val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
    

    4.6.2:集合的函数式api

    现在有一个需求:找到集合中单词最长的水果名 我们可以写出如下代码:

    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    var maxLengthFruit = ""
    for (fruit in list) {
     if (fruit.length > maxLengthFruit.length) {
     maxLengthFruit = fruit
     }
    }
    println("max length fruit is " + maxLengthFruit)
    

    使用集合的函数式api可以简化成如下

    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val maxLengthFruit = list.maxBy { it.length }
    println("max length fruit is " + maxLengthFruit)
    

    上边代码用到了Lambda表达式 ,我们来理解一下lanbda表达式的定义:一段可以作为参数传递的代码,语法结构如下:
    {参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
    可以声明参数列表,参数列表结尾使用->符号表示参数列表的开始和函数体的开始,函数体重可以编写任意行代码(不建议写得太长),并且最后一行代码自动作为Lambda表达式的返回值
    下边来解释一下上边的代码:
    maxBy函数是一个普通函数,他接受一个Lambda 只不过他在遍历集合的时候会将每次遍历的值传递到Lambda中,
    他的工作原理就是根据我们传入的条件来遍历集合 所以我们代码可以写成如下:

    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val lambda = { fruit: String -> fruit.length }
    val maxLengthFruit = list.maxBy(lambda)
    

    定义的lambda表达式如上所示,我们还可以继续简化代码 将Lambda直接放入到maxBy中:

    val maxLengthFruit = list.maxBy({ fruit: String -> fruit.length })
    

    kotlin规定当Lambda参数是函数的最后一个参数可以将Lambda移出到()外边

    val maxLengthFruit = list.maxBy() { fruit: String -> fruit.length }
    

    接下来如果lambda 参数是函数的唯一一个参数的话还可以省略括号

    val maxLengthFruit = list.maxBy{ fruit: String -> fruit.length }
    

    Lambda表达式中大多情况下不必进行参数类型声明:

    val maxLengthFruit = list.maxBy{ fruit -> fruit.length }
    

    另外如果代码中只有一个参数也可以不用声明参数名:

    val maxLengthFruit = list.maxBy { it.length }
    

    牛逼不牛逼吧 ,看管你湿了吗
    另外集合中的map函数是最常用的一种函数式API,他用于将集合中的每个元素都映射成另一个值,映射规则根据Lambda来定
    如果我们希望使集合中水果名都转化为大写:

    fun main() {
     val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
     val newList = list.map { it.toUpperCase() }
     for (fruit in newList) {
     println(fruit)
     }
    }
    

    4.6.3:函数式api all和any

    all判断集合中所有元素都满足指定条件
    any判断集合中的元素至少有一个元素满足条件

    fun main() {
     val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
     val anyResult = list.any { it.length <= 5 }
     val allResult = list.all { it.length <= 5 }
     println("anyResult is " + anyResult + ", allResult is " + allResult)
    }
    

    4.5:空指针检查

    4.5.1:可空系统类型

    在对象后添加?表示这个对象可能是空,使用对象的时候需要添加?.来进行判断 表示是空不执行,否则执行

    fun doStudy(study: Study?) {
     study?.readBooks()
     study?.doHomework()
    }
    

    4.5.2: 判空辅助工具

    编写函数来获取一段文本的长度使用传统的写法

    fun getTextLength(text: String?): Int {
     if (text != null) {
     return text.length
     }
     return 0
    }
    

    借助操作符变得更简单
    ?:操作符。这个操作符的左右两边都接收一个表达式,
    如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。

    fun getTextLength(text: String?) = text?.length ?: 0
    

    !! 告诉Kotlin,我非常确信这里的对象不会为空,但是出现问题我会自己承担

    fun printUpperCase() {
     val upperCase = content!!.toUpperCase()
     println(upperCase)
    }
    

    4.5.3: let标准函数

    fun doStudy(study: Study?) {
     study?.readBooks()
     study?.doHomework()
    }
    

    上边的函数可以使用let函数进行优化 如下

    fun doStudy(study: Study?) {
     study?.let { stu ->
     stu.readBooks()
     stu.doHomework()
     }
    }
    

    lambda表达式如下

    fun doStudy(study: Study?) {
     study?.let {
     it.readBooks()
     it.doHomework()
     }
    }
    

    4.6:字符串内嵌表达式

    val brand = "Samsung"
    val price = 1299.99
    println("Cellphone(brand=" + brand + ", price=" + price + ")")
    

    使用内嵌表达式如下

    val brand = "Samsung"
    val price = 1299.99
    println("Cellphone(brand=$brand, price=$price)")
    

    同样也可以使用如下${函数}直接对函数进行拼接

     println("lambda表达式高阶函数返回的数据是${resultMinus}")
     val resultMinus = num1AndNum2(num1, num2) { n1, n2 ->
            n1 - n2
        }
    

    4.7:函数的默认表达式

    表示一个函数的参数允许存在默认值 这样我们调用的时候可以不传已经存在的值,默认调用默认存在的值

    fun printParams(num: Int, str: String = "hello") {
     println("num is $num , str is $str")
    }
    fun main() {
     printParams(123)
    }
    //也可以使用键值对匹配的方式添加数据,意思就是可以不按照函数中的参数排列方式进行传参,只要键值对对应就可以
    printParams(str = "world", num = 123)
    

    好了关于变量和函数相关的知识告一段落下一篇文章我会输出关于Kotlin的标准函数和静态方法等相关知识~
    点赞加关注!学习不迷路!😬😬😬😬😬😬😬😬😬😬
    有什么问题欢迎留言指出😜😜😜😜😜😜😜😜😜😜

    相关文章

      网友评论

          本文标题:Kotlin:变量和函数

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