Android学习Kotlin之一、常量-条件-函数-高阶函数

Kotlin

Java相对于Kotlin对比,Java的语法太繁琐,Kotlin更现代化, 语法更方便简洁, 可以作为更好的一个替代。Kotlin解决了Java中很多的痛点,进化成一门优秀的语言,给开发者带来了更可靠的开发体验。Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。除此之外Kotlin还可以编译成二进制代码直接运行在机器上(例如嵌入式设备或 iOS)。

Kotlin

为什么学习 Kotlin?

  • 2019 年,谷歌I/O 大会上则宣布 Kotlin 是 Android 应用开发的首选语言。
  • 简洁: 语法简洁,大大减少样板代码的数量。
  • 安全: 减少应用崩溃,避免空指针异常等整个类的错误。
  • 互操作性: 可以和Java互相操作。

其它Kotlin文章
Android学习Kotlin之一、常量-条件-函数-高阶函数
Android学习Kotlin之二、Null安全 -字符串操作- 类型转换
Android学习Kotlin之三、标准库函数-集合List-Set-Map
Android学习Kotlin之四、定义类-初始化-继承
Android学习Kotlin之五、对象-接口-抽象类
Android学习Kotlin之六、泛型-扩展函数

本编文章会讲到的知识点

  • 变量与类型
    • 数据类型
    • 数字类型
    • 变量
    • 类型推算
    • 查看Kotlin字节码
    • Kotlin的引用类型和基本数据类型
  • 条件语句
    • if else
    • range
    • when
  • string模板
  • 函数
    • 定义函数
    • 函数参数
    • Unit函数
    • 反引号中的函数名
  • 高阶函数
    • 匿名函数
    • 函数类型与隐式返回
    • 匿名函数参数
    • it关键值
    • 类型推断
    • 参数为函数
    • 简略传函数参
    • 函数引用
    • 函数类型作为返回类型
    • 闭包
    • lambda与匿名内部类

变量与类型

数据类型

kotlin内置数据类型

类型 描述 示例
String 字符串 "Hello kotlin"
Char 单字符 "A"
Boolean 布尔值 true\false
Number 数值 Byte Short Int Long Float Double
Array 集合 List Set Map

数字类型

和java一样,kotlin中所有的数字类型都是有符号的,可以有正有负,长度各不相同。

类型 最大值 最小值
Byte 8 127 -128
Short 16 32767 -32768
Int 32 2147483647 -2147483648
Long 64 9223372036854775807 -9223372036854775808
Float 32 3.4028235E38 1.4E-45
Double 64 1.7976931348623157E308 4 9E-324

变量

声明变量

声明变量

  • var可变变量 可改变值
var age: Int = 18
age++ //可改变
  • val只读变量 只能赋值一次
val name: String = "甜心"
 name = "baby" // 会报错 使用val定义的变量是不可改变的只能赋值一次

类型推算

对于已声明并赋值的变量,它允许你省略类型定义自动推算类型

var love = "敲键盘" //自动推算类型为String

查看Kotlin字节码

查看Kotlin编译后的字节码,有助于深入了解Kotlin语言

两种方式:

  • Shift两次,输入Show Kotlin
  • Tools>Kotlin>Show Kotlin Bytecode


    Kotlin字节码

Kotlin的引用类型和基本数据类型

  • Java有两种数据类型,一种引用类型一种基本数据类型。
  • Kotlin只有引用类型这一种类型,出于更高性能的需要,Kotlin编译器会在Java字节码中改用基本数据类型。

条件语句

if else

  • java一样
    if (age>18) {
        println("成年了")
    } else {
        println("未成年")
    }
  • 简写方式
println(if (age>18) "已经成年2" else "未成年2")

range

Range是Kotlin相对Java新增的一种表达式,它表示的是值的范围,类似于数学中的区间。Range的表达式是像这样子的:1..20,其中..是运算符,它表示一个闭区间[1, 20]。而右开区间用until表示:1 until 20,即[1, 20)

  • Range表达式一般是和in和!in操作符一起使用,表示是否包含在该区间内
    if (a in 2..10) {//相当于 i >= 2 && i <= 20
        println("我在区间")
    }
    if (a !in 2..10) {//相当于 i < 2 && i > 20
        println("我不在区间")
    }
  • 对于一些整形的range(IntRange、LongRange、CharRange)是可以进行迭代的,它们可以和for循环一起使用
    for (i in 1..6) println(i)//输出123456
  • 使用downTo()函数可以对range进行倒序迭代
for (i in 6 downTo 1) println(i)//输出654321
  • 使用step()函数,这里指定为2,则每次遍历后会以2个为单位遍历
for (i in 8..16 step 2) println(i)//输出8 10 12 14 16

when

when,大家都会联想到 Java 中的 switch,然而在 kotlin 中,when 显然比 Java 中的 switch 要强大得多。when 既可以被当做表达式使用也可以被当做语句使用。如果它被当做表达式。

  • 作为表达式使用,也可以将代码块作为我们的分支体,这时候代码块中最后一个表达式或者变量就是该分支体的返回结果
    var n = "小芳"
    var m = when (n) {
        "小明" -> "我是小明"
        "小芳" -> {
            println("lailai")
            "我是小芳芳"
        }
        "小强" -> "我是小强"
        else -> "未知人"
    }
    println(m)//打印 lailai 我是小芳芳
  • 作为语句使用
    when (n) {
        "小明" -> println("我是小明2")
        "小芳" -> println("我是小芳2")
        "小强" -> {
            println("我是小强2")
        }
        else -> println("未知人2")
    }
  • 可以检测一个值在(in)或者不在(!in)一个区间或者集合中
    when (6) {
        in 1..10 -> {
            var n = 10
            println(n)
        }
        else -> print(66)
    }
  • 检测一个值是(is)或者不是(!is)一个特定类型的值,可以直接使用类型的属性和方法
    var x = "love"
    when (x) {
        is String -> println("love长度= " + x.length)
        else -> false
    }
  • 无参使用,if else if可以改成这样
    when {
        x?.length==4 -> print("长度对的")
        else -> print("长度不对")
    }

string模板

模板支持在字符串的引号内放入变量值;还支持字符串里计算表达式的值并插入结果,添加在${}中的任何表达式,都会作为字符串的一部分求值。

    val man = "沈腾"
    val woman ="贾玲"
    println("$man love $woman")// 打印 沈腾 love 贾玲

    val falg =false
    println("我爱的人是:${if (falg) "邓紫棋" else "张靓颖"}")//打印 我爱的人是:张靓颖

函数

定义函数

private fun doSomething(age:Int,flag:Boolean) :String{
    return "运动"
}
定义函数

函数参数

  • 默认值参数

如果不打算传入参数,可以给参数设置默认值

private fun setStudent(name:String,age:Int=18){
    println("名字:$name , 年龄:$age")
}
 setStudent("郑恺")//没有传age  打印  “名字:郑恺 , 年龄:18”
 setStudent("郑恺",38)//打印 “名字:郑恺 , 年龄:38”
  • 具名函数参数

使用参数命名值传参,就不用管函数中参数的顺序了

private fun setMotion(motion1:String,motion2:String,motion3:String){
    println("运动1:$motion1 , 运动2:$motion2, 运动3:$motion3")
}
setMotion(motion2="游泳",motion1 = "乒乓",motion3 = "爬山")// “运动1:乒乓 , 运动2:游泳, 运动3:爬山“
  • Unit函数

Java中没有返回值的函数定义void类型,而kotlin没有返回值定义Unit返回类型,默认可以不写。

private fun setStudent(name:String,age:Int=18):Unit{
}
private fun setStudent(name:String,age:Int=18){
}

反引号中的函数名

kotlin可以使用空格和特殊字符对函数命名,但是函数名需要用双引号括起来。Kotlin和Java可以互相调用函数,而kotlin和Java各自有着不同的保留关键字不能作为函数名,使用反引号可以解决冲突。

private fun `123`():Int{
    return 666
}
private fun `class`():String{
    return "class"
}
  println(`123`())
  println(`class`())

高阶函数

匿名函数

定义时不取名字的函数,我们称之为匿名函数,匿名函数通常整体传递给其它函数或者从其它函数中返回。

  • 定义匿名函数和调用, {}是匿名函数 ()是调用匿名函数可以传值 匿名函数不支持参数默认值和具名函数参数。
    println({a: Int, b: String ->
        "Welcome to HangZhou, $a!(copyright $b)"
    }(2021, "磐石"))
  • 定义标准库中的函数规则
    //count()函数是获取字符个数
    var totalNum:Int = "missyous".count { letter ->
        letter == 's'
    }
    println("共有s个数=:"+totalNum)

函数类型与隐式返回

匿名函数也有类型,匿名函数可以当做变量赋值给函数类型变量,和其它变量一样,匿名函数就可以在代码里传递了。函数类型由传入的参数和返回值类型决定。
匿名函数一般不需要return关键字来返回数据,那么为了返回数据,匿名函数会隐式返回函数体最后一行语句的结果。

    //定义一个函数nowFun返回类型是String
    val nowFun:()->String
    nowFun = {
        val name= "西塘河"
        "你好 $name"
    }
    // 简写
    val nowFun:()->String= {
        val name= "西塘河"
        "你好 $name"
    }
    println(nowFun()) // 打印 “你好 西塘河”

匿名函数参数

参数的类型放在匿名函数的类型定义中,参数名则放在函数定义中

    var nowFun2: (String,Int) -> String = {name,age->
        "你好 $name 年龄 $age"
    }
    println(nowFun2("马云",50))// 打印 “你好 马云 年龄 50”

it关键值

定义只有一个参数匿名函数时,可以使用it关键字当做参数名,当参数大于1个时it就不能用了。

    var oneParamFun: (String) -> String = {
        "我喜欢:$it"
    }
    println(oneParamFun("林忆莲"))// 打印 “我喜欢:林忆莲”

类型推断

定义一个函数变量时,如果已经把匿名函数赋值给了变量,就不用指定变量类型里了。有参数时,匿名函数的参数名和类型都必须有

    //省略前
    val typeFun:()->String = {
        "我喜欢:"
    }
    //省略后
    val typeFun = {
        "我喜欢:"
    }
    println(typeFun())

    //省略前
    val typeParamFun:(String,String)->String = { name, yarn ->
        "Happy $name $yarn"
    }
    //省略后
    val typeParamFun = { name: String, yarn: String ->
        "Happy $name $yarn"
    }
    println(typeParamFun("彭彭", "2025"))

参数为函数

在函数参数中可以传入函数,可以是匿名函数也可以是普通函数。

    val setTime={goodName:String,yarn:Int->
        "$yarn 天猫双十一 $goodName"
    }

    fun showTime(name:String, showGood:(String,Int)->String){
        val yarn = (2020..2030).shuffled().last()
        println(showGood(name,yarn))
    }

    showTime(name = "关晓彤",setTime)

简略传函数参

如果一个函数的lambda参数排在最后或者是唯一的参数,那么括住lambda值的圆括号就可以省略掉了。

    showTime(name = "容祖儿"){goodName:String,yarn:Int->
        "$yarn 天猫双十一 $goodName"
    }

函数引用

上面讲过了 把函数当成参数传给一个函数使用,不光可以传递匿名函数也可以传递具名函数的引用,只要可以使用lambda表达式地方都可以使用函数引用。

    fun setStudent(name:String,age:Int):String{
        return "我是六年级的 $name 今年 $age 岁了"
    }
    fun setClass(name:String,student:(String,Int)->String){
        println(student(name,12))
    }
    setClass("黄晓明", ::setStudent)//打印 “我是六年级的 黄晓明 今年 12 岁了”

函数类型作为返回类型

一个函数的返回值可以使一个函数(包括匿名函数和具名函数)。

    fun getFruit():(String)->String{
        val currYarn = 2021
        return {fruitName:String->
            "$currYarn 我喜欢吃 $fruitName"
        }
    }
    val fruit = getFruit()//返回的是个匿名函数
    println(fruit("樱桃"))// 打印 “2021 我喜欢吃 樱桃”

闭包

在Kotlin中,匿名好处能够修改并应用定义在自己的作用域之外的变量,匿名函数引用着定义自身的函数里的变量,Kotlin中的lambda就是闭包。
能接收函数或者返回函数的函数又叫做高级函数,高级函数广泛用于函数式编程当中。

lambda与匿名内部类

为什么要在代码中使用函数类型?函数类型能让开发者少写模式化代码,写出更灵活的代码。Java8支持lambda表达式,但不支持将函数作为参数传递给另一个函数或者变量,不过Java的替代方案是匿名函数。

  • Kotlin使用匿名函数

kotlin使用匿名内部类直接创建就行

    //定义一个函数最后一个参数是lamdba匿名函数
    fun setPhone(phoneName: String, moneyDeta: (String, Int) -> Unit) {
        val money = if (phoneName == "iphone12") 5800 else 6000
        moneyDeta(phoneName, money)
    }
    // 调用函数传入一个lamdba匿名函数
    setPhone("iphone12") { phoneName: String, money: Int ->
        println("$phoneName 价格为 $money")
    }
  • Java中使用匿名函数

java使用匿名内部类需要先创建一个接口

    public static void main(String[] args) {
      // 通过new一个匿名内部类传过去
        setPhone("iphone12", new MoneyDeta() {
            @Override
            public void setMoney(String phoneName, int money) {
                System.out.println(phoneName+" 价格为 "+ money);
            }
        });
    }
    public static void setPhone(String phoneName,MoneyDeta moneyDeta){
        int money = "iphone12".equals(phoneName)? 5800:6000;
        moneyDeta.setMoney(phoneName,money);
    }
    //定义接口
    public interface MoneyDeta{
        void setMoney(String phoneName,int money);
    }

你可能感兴趣的:(Android学习Kotlin之一、常量-条件-函数-高阶函数)