当前位置: 首页 > article >正文

【Android】Kotlin教程(1)

文章目录

      • 1.声明变量
      • 2.类型推断
      • 3.range表达式
      • 4.when表达式
      • 5.string模版
      • 6.函数
      • 7.数据类型
      • 8.匿名函数
      • 9.函数参数
      • 10.it关键字
      • 11.匿名函数的类型推断
      • 12.lambda
      • 13.函数内联
      • 13.函数引用
      • 14.高阶函数
      • 15.闭包

1.声明变量

可变变量定义:var 关键字

var a:Int = 1

不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)

val a:Int = 1

2.类型推断

类型推断:对于已声明赋值的变量,它允许省略类型定义。
在这里插入图片描述

3.range表达式

in A…B 关键字用来检查某个值是否在指定范围之内。

	if(age in 0..18){
        println("少年")
    }else if(age in 18..40){
        println("成年")
    }

4.when表达式

  • 允许你编写条件式,在某个条件满足时,执行对应代码
  • 只要包含else if分支,都建议改用when表达式
    val school = "小学"
    val level = when(school){
        "小学" -> 1
        "初中" -> 2
        "高中" -> 3
        else -> 0
    }
    println("level: " + level);

5.string模版

  • 模版支持在字符串的引号内放入变量值。
  • 还支持字符串里计算表达式的值并插入结果,添加在${}中的任何表达式,都会作为字符串的一部分求值。
    val school = "小学"
    println("$school")
    
    val flag = false
    println("Answer is : ${if(flag) "Yes" else "No"}")

6.函数

函数定义使用关键字 fun,参数格式为:参数 : 类型

fun add(a:Int , b:Int):Int{
    return a+b;
}

无返回值的函数

fun addNoReturn1(a:Int,b:Int,c:Int = 1){
    println("结果" + (a+b+c))
}

fun addNoReturn2(a:Int,b:Int,c:Int = 1) :Unit{
    println("结果" + (a+b+c))
}

可变长参数函数

fun addToSum(vararg nums:Int):Int{
    var sum = 0
    for(num in nums){
        sum += num
    }
    return sum
}

7.数据类型

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

Kotlin 提供了多种内置数据类型,这些类型大致可以分为以下几类:
整数类型

  • Byte:8位有符号整数
  • Short:16位有符号整数
  • Int:32位有符号整数
  • Long:64位有符号整数

浮点类型:

  • Float:32位单精度浮点数
  • Double:64位双精度浮点数

字符类型

  • Char:表示一个单一的 16 位 Unicode 字符

布尔类型

  • Boolean:表示逻辑上的真(true)或假(false)

数组类型

  • 数组是一种用于存储固定大小的同类型元素的集合。例如,IntArray 用来存放整数数组,Array 用来存放字符串数组等。

字符串类型

  • String:不可变的字符序列

除了上述的基本类型外,Kotlin 还提供了一些特殊的类型如 Unit 和 Nothing:

  • Unit 类型类似于 Java 中的 void,它代表没有任何信息的值。如果一个函数没有返回任何有意义的结果,那么它的返回类型就是 Unit。
  • Nothing 类型则代表一个永远不会返回结果的函数。这种类型的函数通常用于抛出异常或者无限循环中。
    另外,Kotlin 不像 Java 那样区分原始类型和包装类型,所有的数值类型都是对象。但是,为了性能考虑,Kotlin 在后台会自动处理这些类型的特殊优化,使得它们的行为类似于 Java 的原始类型。

8.匿名函数

  • 定义时不取名字的函数,我们称之为匿名函数,匿名函数通常整体传递给其他函数,或者从其他函数返回。
fun main() {
    val total = "Mississippi".count()
    val count = "Mississippi".count { it == 's' }
    println(total)
    println(count)
}

9.函数参数

和具名函数一样,匿名函数可以不带参数,也可以带一个或者多个任何类型的参数,需要带参数时,参数的类型放在匿名函数的类型定义中,参数名则放在函数定义中。

 val blessingFunction:(String) -> String = { name ->
        val holiday = "New Year"
        "Happy $holiday $name"
    }

    println(blessingFunction("Jack"))

在这里插入图片描述

10.it关键字

定义只有一个参数的匿名函数时,可以使用it关键字来表示参数名。当你需要传入两个值参,it关键字就不能用了。
在这里插入图片描述

11.匿名函数的类型推断

定义一个变量时,如果已把匿名函数作为变量复制给它,就不需要显示指明变量类型。

    val blessingFunction = {
        val holiday = "New Year"
        "Happy $holiday"
    }

    println(blessingFunction())

类型推断也支持带参数的匿名函数,但为了帮助编译器更准确地推断变量的类型,匿名函数的参数名和参数类型必须有。

    val blessingFunction:(String,Int)-> String = { name:String,year:Int ->
        val holiday = "New Year"
        "$year $name Happy $holiday"
    }
    val blessingFunction = { name:String,year:Int ->
        val holiday = "New Year"
        "$year $name Happy $holiday"
    }

12.lambda

Lambda 表达式的完整语法形式如下:

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
  • lambda 表达式总是括在花括号中。
  • 完整语法形式的参数声明放在花括号内,并有可选的类型标注。
  • 函数体跟在一个 -> 之后。
  • 如果推断出的该 lambda 的返回类型不是 Unit,那么该 lambda 主体中的最后一个(或可能是单个)表达式会视为返回值。
val sum = { x: Int, y: Int -> x + y }

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

fun main() {

    val getDiscountWords = {goodsName : String,hour : Int ->
        val  currentYear = 2024
        if (hour > 12){
            "Discount for $goodsName in $currentYear $hour"
        }else{
            "No Discount for $goodsName in $currentYear $hour"
        }
    }

    showOnBoard("iPhone"){ goodsName,hour ->
        val  currentYear = 2024
        if (hour > 12){
            "Discount for $goodsName in $currentYear $hour"
        }else{
            "No Discount for $goodsName in $currentYear $hour"
        }
    }
}


fun showOnBoard(goodsName:String , getDiscountWords:(String,Int) -> String){
    val hour = (1..24).shuffled().last()
    println(getDiscountWords(goodsName,hour))
}

13.函数内联

内联(inline)函数是一种特殊的函数,它允许编译器将函数的调用处直接替换为函数体的代码。这种方式可以消除函数调用的开销,并且对于一些高阶函数(即接受其他函数作为参数或返回其他函数的函数)特别有用,因为它们通常会创建闭包对象来存储 lambda 表达式的上下文。

为什么使用内联?

  • 性能提升:通过消除函数调用的开销,尤其是当函数非常小的时候,内联可以提高程序的执行效率。
  • 非局部返回:内联函数中可以使用 return 直接从外部作用域返回,这在普通的函数中是不允许的。
  • 重载解析:内联函数可以在被调用时进行更精确的类型推断,从而影响到方法重载的选择。
  • 减少闭包对象的创建:当传递 lambda 表达式给函数时,如果没有内联,lambda 会被包装成一个对象。内联则可以直接将 lambda 的代码插入到调用处,避免了这种开销。

13.函数引用

函数引用是一种将函数本身作为值传递给其他代码的方式。这使得你可以像处理任何其他值一样处理函数,例如将它们存储在变量中、作为参数传递或从函数返回。Kotlin 提供了简洁的语法来创建函数引用,并且这些引用可以用于各种场景,比如与高阶函数一起使用。

函数引用的基本形式:创建一个函数引用,你只需要使用 :: 操作符加上函数名。

fun main() {

    showOnBoard("Laptop",::getDiscountWords)
}

private fun getDiscountWords(goodsName: String,hour:Int) : String {
    val  currentYear = 2024
    return if (hour > 12){
        "Discount for $goodsName in $currentYear $hour"
    }else{
        "No Discount for $goodsName in $currentYear $hour"
    }
}


private fun showOnBoard(goodsName:String , getDiscountWords:(String,Int) -> String){
    val hour = (1..24).shuffled().last()
    println(getDiscountWords(goodsName,hour))
}

14.高阶函数

函数类型也是有效的返回类型,也就是说可以定义一个能返回函数的函数。

fun main(){
    val getDiscountWords: (String) -> String = configDiscountWords()
    println(getDiscountWords("Apple"))
}

fun configDiscountWords() : (String) -> String {

    return { goodsName ->
        val  currentYear = 2024
        val hour = (1..24).shuffled().last()
        if (hour > 12){
            "Discount for $goodsName in $currentYear $hour"
        }else{
            "No Discount for $goodsName in $currentYear $hour"
        }
    }
}

15.闭包

在Kotlin中,匿名函数能修改并引用定义在自己作用域之外的变量,匿名函数引用着定义自身的函数里的变量,在Kotlin中的lambda就是闭包。

fun createCounter(): () -> Int {
    var count = 0  // 定义一个可变的局部变量
    return {
        count++  // lambda 捕获了 count 变量
    }
}

val counter = createCounter()
println(counter())  // 输出 1
println(counter())  // 输出 2

在这个例子中,createCounter 函数返回一个 lambda 表达式,该表达式每次调用时都会增加 count 的值。尽管 count 是在 createCounter 内部定义的局部变量,但返回的 lambda 仍然可以访问它,这就是闭包的作用。

注意事项:

  • 性能考虑:闭包可能会导致额外的内存开销,因为需要保持对捕获变量的引用。如果捕获的是大对象或大量数据,这可能会影响性能。
  • 变量捕获:在 Kotlin 中,lambda 表达式只能捕获那些在创建时就已经声明为 val 或 var 的变量。如果你尝试捕获一个没有初始化的变量,编译器会报错。
  • 不可变性:为了保证线程安全,通常建议只捕获不可变的数据。如果确实需要捕获可变状态,确保正确处理并发问题。

http://www.kler.cn/news/365771.html

相关文章:

  • kafka 如何减少数据丢失?
  • linux网络编程5——Posix API和网络协议栈,使用TCP实现P2P通信
  • 李沐读论文-启发点记录2:Resnet--残差连接--kaiming老师神作
  • JSON Web Token (JWT)的简单介绍、验证过程及令牌刷新思路
  • 基于springboot企业微信SCRM管理系统源码带本地搭建教程
  • Unity-Editor扩展,引擎管理AudioClip,音乐音效快捷播放功能
  • C#从零开始学习(用户界面)(unity Lab4)
  • UE5 第一人称示例代码阅读0 UEnhancedInputComponent
  • python实现斗地主
  • qt项目使用其他项目的.ui之指针
  • RabbitMQ安装部署
  • Elliott Wave Prophet,艾略特波浪预测指标!预测未来走势!免费公式!(指标教程)
  • 考研篇——数据结构王道3.2.2_队列的顺序实现
  • 大一物联网要不要转专业,转不了该怎么办?
  • Scala的多态:定义,作用,实现手法
  • AUTOSAR从入门到精通-英飞凌GTM模块
  • Go语言生成UUID的利器:github.com/google/uuid
  • Node.js 路由
  • 文本预处理——构建词云
  • 【云效】阿里云云效:一站式DevOps平台介绍与使用教程(图文)附PPT
  • 2024 项目管理工具大变革:Jira 的替代者是谁?
  • 【数据分享】全国各省份农业-瓜果类面积(1993-2018年)
  • Python+Django+VUE 搭建深度学习训练界面 (持续ing)
  • CRLF、UTF-8这些编辑器右下角的选项的意思
  • STM32Lx GXHT3x SHT3x iic 驱动开发应用详解
  • 【Git】将本地代码提交到github仓库