Kotlin 之表达式详解

简介: Kotlin 之表达式详解

常量和变量


fun main() {
    //变量
    var a: Int = 2
    a = 3
    //只读变量,在局部中,和 final 相同
    val b = 2
    //如果是全局
    val x = X()
    println(x.b) //每次的值都不一样
    /**
     * 长量引用
     * 创建的对象在 堆 上
     * 对象内部内容可以改变,但是对象不能改变
     */
    val x1 = X()
}
/**
 * 常量
 * 只能定义在全局范围
 * 只能修饰基本类型
 * 必须立即用字变量初始化
 * 和 java 中的 static final 基本相同
 */
const val b = 2 // 编译时即可确定常量的值,并用值替换调用处
val c: Int  //运行时才能确定值
    get() {
        TODO()
    }
class X {
    //属性
    val b: Int
        get() {
            return (Math.random() * 100).toInt()
        }
}


分支表达式


fun main() {
    var c = 4
    // if else 表达式
    c = if (c == 4) 3 else 9
    println(c)
    //分支,类似于 switch,但是不用写 break
    when (c) {
        0 -> c = 2
        1 -> c = 3
        else -> c = 20
    }
    //简化
    c = when (c) {
        0 -> 2
        1 -> 3
        else -> 20
    }
    //条件转移到分支
    var x: Any = ""
    when {
        x is String -> x = "哈哈哈"
        x is Int -> x = 10
        else -> x = 90
    }
    //简化
    x = when (x) {
        is String -> "哈哈哈"
        is Int -> 10
        else -> 90
    }
    //when...
    x = when (val input = readLine()) {
        null -> ""
        else -> input.length
    }
    //try ... catch 表达式
    x = try {
        3 / 0
    } catch (e: Exception) {
        e.printStackTrace()
        0
    }
}


运算符


Kt 中支持运算符重载


运算符的范围仅限官方指定的符号


指定的符号


Kt 允许我们为自己的类型提供预定义的一组操作符的实现,这些操作符举要固定的符号表示,如 + * 等。为实现这样的操作符,Kt 为相应的类型提供了一个固定名字的成员函数或者扩展函数。重载操作符需要使用 operator 修饰符标记。


如下:


fun main() {
    val point = Point(10, 20)
    println(point - 10) //0
}
class Point(val x: Int, val y: Int) {
    //重载 - 号
    operator fun minus(num: Int): Int {
        return x - num
    }
}


fun main() {
    val point = Point(10, 20)
    println(point[0]) //10
    println(point[1]) //20
    println(point[2]) //java.lang.IndexOutOfBoundsException
}
class Point(val x: Int, val y: Int) {
    //重载 get
    operator fun get(index: Int): Int {
        return when (index) {
            0 -> x
            1 -> y
            else -> throw IndexOutOfBoundsException()
        }
    }
}


官方中文文档


中缀表达式


fun main() {
    println("Hello" to "Word")
}
/**
 * 中缀表达式
 * 必须加 infix 标识
 * 只有一个参数,并且是扩展方法
 */
infix fun String.rotate(str: String): String {
    return this + str
}


函数的表达式形式


fun main() {
    println(add(1, 2))
    println(add2(2, 3))
}
fun add(x: Int, y: Int): Int {
    return x + y
}
//如果函数中只有一句或者为一个表达式,可以这样写
fun add2(x: Int, y: Int): Int = x + y


Lambad 表达式


fun main() {
    /**
     * 将匿名函数赋值给一个变量
     * fun1 是变量名
     * 调用 fun1()
     */
    val fun1 = fun() {
        println("匿名函数")
    }
    //Lambad 其实就是匿名函数
    val l1 = {
        println("lambad")
    }
    //带参数的 Lambad
    val l2 = { p: Int ->
        println("带参数的 Lambad")
    }
    // 表达式中最后一行为返回值,可不加 return
    val l3 = { p: Int ->
        println(p)
        "Hello Word"
    }
    //表达式中如果只有一个参数,可以用 it 代替
    val l4: Function1<Int, Unit> = {
        println(it)
    }
    l4(123)
    //第二个参数接收一个Lambad 表达式,接收一个 Int 参数,并返回一个 Int 参数
    IntArray(2) { i ->
        0
    }
    fun3() { x: Int, y: Int ->
        println("${x + y}")
        "$x + $y"
    }
}
//接收两个 int 类型,返回一个 String 类型的函数
fun fun3(sum: (Int, Int) -> String) {
    println(sum(2, 3))
}
fun fun0() {
    println("普通函数")
}


案例1


实现 equals 和 hashCode


fun main() {
    val hashSet = hashSetOf<Person>()
    (0..5).forEach { _ ->
        hashSet += Person(30, "张三")
    }
    println(hashSet.size)
    //注意:将对象添加到集合后就不要改变对象的数据,否则会造成无法删除,从而引发内存泄露
}
class Person(private val age: Int, private val name: String) {
    override fun equals(other: Any?): Boolean {
        val o = (other as? Person) ?: return false
        return age == o.age && name == o.name
    }
    override fun hashCode(): Int {
        return 31 + age * 7 + name.hashCode()
    }
}


案例2


实现 String 的四则运算


fun main() {
    val value = "HelloWorld"
    println(value - "World")
    println(value * 3)
    println(value / "l")
}
// - 替换第一个出现的字符串
operator fun String.minus(right: Any?): String =
    this.replaceFirst(right.toString(), "")
// * 链接一个字符串
operator fun String.times(count: Int): String {
    return (1..count).joinToString(" ") { this }
}
// / 找出出现多少次
operator fun String.div(right: Any?): Int {
    val r = right.toString()
    //根据传入的字符串,从 this 中挨个进行查找
    //如 length = 2,那就是 " he , el ,ll ,lo , ow ... "
    //最后一个参数是表达式,所以可以移到外面
    return this.windowed(r.length, 1) {
        //判断是否相等
        it == r
    }.count {
        //计数,
        it
    }
}


总结


常量和变量

定义方式:var / val /const val

常量按类型分类

常量值

常量引用

常量按时期分类

编译器常量

运行时常量

分支表达式

if else

when …

try … catch

运算符

常见的运算符

“+ - * /”

“. < ==”

“ in ”

" get "

" invoke "

运算符的重载

中缀表达式:必须有 infix 标识,是扩展方法,并且只有一个参数

函数的表达式形式:如果函数中只有一句话或者一个表达式,可直接赋值给 函数

Lambad

匿名函数 :本质是匿名函数,匿名函数不能直接使用,需要一个变量来接收,然后调用这个变量就能间接的调用这个匿名函数

写法

类型

类型推断:如果左边定义中已经写了具体的类型声明,后面的实现就可以不用写。反之,后面则需要具体的声明


相关文章
|
9月前
|
Java 编译器 Kotlin
Kotlin 中变量,类型,表达式,函数详解
Kotlin 中变量,类型,表达式,函数详解
68 0
|
Java 开发者 Kotlin
Kotlin中lambda表达式详解
lambda运算时java后面版本引进的,所以实现的仅仅是从形式上简化代码,内部的优化并不是非常出色,而Kotlin一开始就支持函数式编程,使得其lambda表达式具有性能上的优势,同时Kotlin简洁的风格也给lambda表达式进一步简化提供了一个良好的实现方式,下面带大家具体看看他们之间的区别以及如何更好的使用Kotlin的极简化lambda表达式
134 0
Kotlin中lambda表达式详解
|
算法 Java 编译器
Kotlin学历之函数与Lambda表达式
Kotlin学历之函数与Lambda表达式
79 0
|
Java Kotlin
【Kotlin】Lambda 表达式 ( 简介 | 表达式语法 | 表达式类型 | 表达式返回值 | 调用方式 | 完整示例 )
【Kotlin】Lambda 表达式 ( 简介 | 表达式语法 | 表达式类型 | 表达式返回值 | 调用方式 | 完整示例 )
259 0
【Kotlin】Lambda 表达式 ( 简介 | 表达式语法 | 表达式类型 | 表达式返回值 | 调用方式 | 完整示例 )
|
数据安全/隐私保护 Kotlin
Kotlin表达式(中缀、分支、When)
1、中缀表达式 只有一个参数,且用infix修饰的函数 例如: //书 class Book{ //infix 自定义运算符的中缀表达式。
1176 0
Kotlin的Lambda表达式
一、什么是Lambda表达式 就是匿名函数 写法:{[参数列表] -> [函数体,最后一行是返回值]} **举例:**val sum = {a: Int, b: Int -> a+b} 二、Lambda 的类型 ()-...
1330 0
|
Java Kotlin 编译器
Kotlin学习(二)—— 基本语法,函数,变量,字符串模板,条件表达式,null,类型检测,for,while,when,区间,集合
一.基本语法 Kotlin的很多概念跟JAVA是有类似的,所以我应该不会像我的JAVA之旅一样那么的详细,但是不用担心,你会看的很明白的,我也是根据官方的文档来学习的 我们在IDEA中创建一个项目Kotlin02 1.
1594 0
|
Kotlin
Kotlin语法(函数和lambda表达式)
三、函数和lambda表达式 1. 函数声明 fun double(x: Int): Int { } 函数参数是用 Pascal 符号定义的 name:type。参数之间用逗号隔开,每个参数必须指明类型。
770 0
|
6天前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【4月更文挑战第30天】在移动开发领域,随着用户需求的不断增长和设备性能的持续提升,实现流畅且高效的用户体验已成为开发者的首要任务。针对Android平台,Kotlin协程作为一种新兴的异步编程解决方案,以其轻量级线程管理和简洁的代码逻辑受到广泛关注。本文将深入探讨Kotlin协程的概念、优势以及在实际Android应用中的运用,通过实例演示如何利用协程提升应用性能和响应能力,为开发者提供一条构建更高效Android应用的实践路径。
|
2天前
|
移动开发 前端开发 Android开发
构建高效Android应用:探究Kotlin协程的优势
【5月更文挑战第4天】 在移动开发领域,尤其是对于Android开发者而言,编写响应迅速且高效的应用程序至关重要。Kotlin作为一种现代的编程语言,其提供的协程特性为异步编程带来了革命性的改变。本文将深入探讨Kotlin协程在Android开发中的应用优势,并通过实例代码展示如何利用协程简化异步任务处理,提高应用性能和用户体验。