Kotlin入门到深入加强(3): 运算符与表达式详解

目录

一Kotlin运算符详解:

1.Kotlin的运算符分类

1.算术运算符

 2.比较运算符:

3. 逻辑运算符 :

4.赋值运算符:

 5. 位运算符:

 6. 特殊运算符:

 End:

2.运算符优先级:

1.最高优先级

1.括号运算符()

2.数组下标和成员访问[]  和  、

 3.函数调用

4.类型转换as、as?

 2.次高级优先

5.一元运算符

6.按位取反 inv()

3.中等优先级

7.乘法、除法和取模运算*、/、%

8.加法和减法+、-

9.范围运算符、、

10.类型检查 is、!is

4.较低优先级

11.比较运算符 <、<=、>、>=

12.等价性运算符 ==、!=

13.按位运算符 shl、shr、ushr、and、or、xor

5.最低优先级

逻辑运算符

赋值运算符

3.运算符重载(进阶内容)

什么是运算重载?

运算重载的核心

运算符重载的示例分类

1.数学运算符

2.比较运算符

 3.索引运算符

4.单目运算符

运算符重载的注意事项

实战案例(可选):


一Kotlin运算符详解:

本章内容将会介绍Kotlin的所有运算符及其作用和特性

1.Kotlin的运算符分类

在Kotlin中,运算符是一种特殊的符号或关键词,用于操作数据,Kotlin提供了丰富的运算符并支持运算符重载,使得它在表达式构建方面非常的灵活,接下来,我会依次介绍各种运算符

1.算术运算符

这些运算符主要用于数学运算

运算符描述示例结果
+加法a + b两数之和
-减法a - b两数之差
*乘法a * b两数之积
/除法a / b两数之商
%求余(模)a % b两数的余数

示例:

fun main() {
    val a = 10
    val b = 3
    
    // 加法运算
    println("Addition: ${a + b}") // 13

    // 减法运算
    println("Subtraction: ${a - b}") // 7

    // 乘法运算
    println("Multiplication: ${a * b}") // 30

    // 除法运算
    println("Division: ${a / b}") // 3

    // 求余运算
    println("Modulus: ${a % b}") // 1
}

 2.比较运算符:

用于比较两个值,结果是布尔类型

运算符描述示例结果
>大于a > btruefalse
<小于a < btruefalse
>=大于或等于a >= btruefalse
<=小于或等于a <= btruefalse
==等于(值比较)a == btruefalse
!=不等于a != btruefalse

示例:

fun main() {
    val x = 5
    val y = 10

    // 判断 x 是否大于 y
    println(x > y) // false

    // 判断 x 是否小于等于 y
    println(x <= y) // true

    // 判断 x 是否等于 y
    println(x == y) // false

    // 判断 x 是否不等于 y
    println(x != y) // true
}

3. 逻辑运算符 :

用于布尔逻辑运算,结果为布尔值

运算符描述示例结果
&&与(AND)a && btrue 当且仅当 a 和 b 都为 true
``或(OR)
!非(NOT)!atrue 转为 false,反之亦然

示例:

fun main() {
    val a = true
    val b = false

    // 与运算:a 和 b 都为 true 时返回 true
    println(a && b) // false

    // 或运算:a 或 b 只要有一个为 true 返回 true
    println(a || b) // true

    // 非运算:取反 a 的值
    println(!a) // false
}

4.赋值运算符:

用于将值赋给变量

运算符描述示例
=赋值a = 10
+=加并赋值a += b 相当于 a = a + b
-=减并赋值a -= b 相当于 a = a - b
*=乘并赋值a *= b 相当于 a = a * b
/=除并赋值a /= b 相当于 a = a / b
%=模并赋值a %= b 相当于 a = a % b

示例:

fun main() {
    var a = 10
    
    // 加并赋值:a += 5 相当于 a = a + 5
    a += 5
    println(a) // 15

    // 乘并赋值:a *= 2 相当于 a = a * 2
    a *= 2
    println(a) // 30

    // 减并赋值:a -= 3 相当于 a = a - 3
    a -= 3
    println(a) // 27
}

 5. 位运算符:

用于对位进行操作

运算符描述示例
shl左移a shl 2
shr右移a shr 2
ushr无符号右移a ushr 2
and按位与a and b
or按位或a or b
xor按位异或a xor b
inv按位取反a.inv()

示例:

fun main() {
    val a = 5 // 二进制:0101
    
    // 左移:将 a 的位左移一位,结果为 1010(二进制)
    println(a shl 1) // 10

    // 右移:将 a 的位右移一位,结果为 0010(二进制)
    println(a shr 1) // 2

    // 按位与:a 和 3 按位与,结果为 0001(二进制)
    println(a and 3) // 1

    // 按位或:a 和 2 按位或,结果为 0111(二进制)
    println(a or 2)  // 7
}

 6. 特殊运算符:

运算符描述示例
in检查值是否在集合中x in list
!in检查值是否不在集合中x !in list
is检查对象是否为特定类型x is String
!is检查对象是否不是特定类型x !is Int

示例::

fun main() {
    val list = listOf(1, 2, 3)

    // 判断 2 是否在 list 中
    println(2 in list) // true

    // 判断 4 是否不在 list 中
    println(4 !in list) // true

    val x: Any = "Kotlin"
    
    // 判断 x 是否为 String 类型
    println(x is String) // true

    // 判断 x 是否不是 Int 类型
    println(x !is Int) // true
}

 End:

这些分类涵盖了 Kotlin 中的所有运算符。每个运算符都有明确的用途,通过实际代码练习和理解公式逻辑,可以灵活运用在项目开发中




2.运算符优先级:

Kotlin中运算符优先级从高到低分为以下几个层次

1.最高优先级

1.括号运算符()

用于显示地定义计算顺序

( a + b) * c 保证先计算a+b

val result = 5 + 3 * 2
println(result) //输出:11

 解释:*的优先级高于+,所以3*2先被计算,结果为6,再计算5+6

若改变括号顺序:

val result = (5 + 3) * 2
println(result) // 输出: 16

2.数组下标和成员访问[]  和  、

arr[0]、obj.property 

 3.函数调用
myFunction(arg1,arg2)
4.类型转换as、as?

obj as String

 2.次高级优先

5.一元运算符

包括

  • 正负号:+、-

       例:   -a

  • 递增和递减: ++、--

       例 ++a、a--

  • 取非: !

       例: !isValid

6.按位取反 inv()
  • 例:  a.inv()

3.中等优先级

7.乘法、除法和取模运算*、/、%
  •  例: a * b  / c
8.加法和减法+、-
  • 例: a+b-c
9.范围运算符、、
  • 例: 1..10创建一个从1到10的范围
10.类型检查 is、!is
  • 例: a is Int

4.较低优先级

11.比较运算符 <<=>>=
  • 示例:a < b
12.等价性运算符 ==!=
  • 示例:a == b
13.按位运算符 shlshrushrandorxor
  • 示例:a and b

5.最低优先级

  1. 逻辑运算符
    • 逻辑与&&
      示例:a && b
    • 逻辑或||
      示例:a || b
  2. 赋值运算符
    • 简单赋值:=
    • 复合赋值:+=-=*=/=%=
    • 示例:a = ba += 2

3.运算符重载(进阶内容)

什么是运算重载?

运算重载是Kotlin提供的一种能力,它允许我们为自定义的类定义现有运算符的能力,换句话说,Kotlin中的某些运算符可以通过特殊的函数来重新定义它们的功能

运算重载的核心

1.需要使用operator关键字声明重载函数

2.只能重载Kotlin预定义的运算符

3.函数名必须符合Kotlin运算符对应的函数签名


运算符重载的示例分类

1.数学运算符
  • 常见数学运算符 +-*/% 都可以被重载

示例:定义一个向量类

// 定义一个数据类 Vector,表示二维向量
data class Vector(val x: Int, val y: Int) {

    // 运算符重载函数,重载 + 运算符
    operator fun plus(other: Vector): Vector {
        // 返回一个新的 Vector,其 x 和 y 是当前向量与另一个向量对应分量相加的结果
        return Vector(x + other.x, y + other.y)
    }
}

fun main() {
    // 创建两个向量实例 v1 和 v2
    val v1 = Vector(3, 4) // 第一个向量,x=3, y=4
    val v2 = Vector(1, 2) // 第二个向量,x=1, y=2

    // 使用 + 运算符对两个向量进行相加
    val result = v1 + v2

    // 打印相加结果,结果为一个新的 Vector(x=4, y=6)
    println(result) // 输出: Vector(x=4, y=6)
}
2.比较运算符
  • 重载 ><>=<= 需要实现 compareTo 函数。

示例:比较分数大小

// 定义一个表示分数的数据类 Fraction
data class Fraction(val numerator: Int, val denominator: Int) : Comparable<Fraction> {

    // 重载 compareTo 运算符,用于比较两个 Fraction 对象
    operator fun compareTo(other: Fraction): Int {
        // 通过交叉相乘比较两个分数的大小,避免直接浮点数计算
        // 计算公式: (a/b ? c/d) 等价于 (a * d ? c * b)
        return (this.numerator * other.denominator) - (this.denominator * other.numerator)
        // 返回值:
        // > 0 表示当前分数大于 other
        // < 0 表示当前分数小于 other
        // == 0 表示两个分数相等
    }
}

fun main() {
    // 创建两个分数实例 f1 和 f2
    val f1 = Fraction(1, 2) // 分数 f1 表示 1/2
    val f2 = Fraction(2, 3) // 分数 f2 表示 2/3

    // 使用 < 运算符比较两个分数的大小
    // 因为 Fraction 类实现了 Comparable 接口,并重载了 compareTo 方法
    println(f1 < f2) // 输出: true
    // 解释: 1/2 < 2/3,因为 1*3 (3) 小于 2*2 (4)
}
 3.索引运算符
  • 使用 getset 函数重载 [] 运算符。

示例:自定义矩阵

// 定义一个矩阵类 Matrix,用于表示和操作二维矩阵
class Matrix(private val data: Array<IntArray>) {

    // 重载 get 运算符,用于通过下标获取矩阵中的元素
    operator fun get(row: Int, col: Int): Int {
        // 返回指定行和列的元素
        return data[row][col]
    }

    // 重载 set 运算符,用于通过下标设置矩阵中的元素
    operator fun set(row: Int, col: Int, value: Int) {
        // 将指定位置的元素更新为新的值
        data[row][col] = value
    }
}

fun main() {
    // 创建一个 2x2 的矩阵,初始值为 [[1, 2], [3, 4]]
    val matrix = Matrix(arrayOf(intArrayOf(1, 2), intArrayOf(3, 4)))

    // 使用自定义的 get 运算符,获取矩阵第 0 行第 1 列的元素
    println(matrix[0, 1]) // 输出: 2

    // 使用自定义的 set 运算符,将矩阵第 0 行第 1 列的值更新为 99
    matrix[0, 1] = 99

    // 再次获取矩阵第 0 行第 1 列的值,验证修改是否成功
    println(matrix[0, 1]) // 输出: 99
}
4.单目运算符
  • 例如 +a-a,需要重载 unaryPlusunaryMinus

示例:反向编辑

// 定义一个表示二维向量的数据类 Vector
data class Vector(val x: Int, val y: Int) {

    // 重载一元运算符 -,用于求向量的相反向量
    operator fun unaryMinus(): Vector {
        // 返回一个新的 Vector,其 x 和 y 分量分别取反
        return Vector(-x, -y)
    }
}

fun main() {
    // 创建一个向量实例 v,x=3, y=4
    val v = Vector(3, 4)

    // 使用重载的 - 运算符求相反向量
    println(-v) // 输出: Vector(x=-3, y=-4)
}
运算符重载的注意事项
  1. 语义一致性

    重载后的运算符应该符合原本的语义。例如,重载 + 应该表示加法或类似的行为,避免令人困惑的实现。

  2. 性能考虑

    运算符重载本质上是方法调用,频繁使用可能有额外的性能开销。

  3. 不能重载所有运算符

    例如,&&|| 是短路运算符,不能被重载。

  4. 代码可读性

    滥用运算符重载可能导致代码难以理解。合理使用可提高可读性,滥用则可能造成混淆。

实战案例(可选):

  • 实现一个简单的计算器:支持基础的四则运算,结合用户输入
  • 集合操作练习:判断一个数是否在特定区间内,结合表达式进行优化

解:

fun main() {
    // 提示 
    println("请输入表达式(例如:3 + 4):")

    // 获取用户输入
    val input = readLine() ?: return // 如果输入为空,直接退出程序

    // 使用正则表达式匹配输入格式,提取操作数和运算符
    val regex = """(\d+)\s*([\+\-\*/])\s*(\d+)""".toRegex()
    val matchResult = regex.matchEntire(input)

    // 检查输入是否匹配正则表达式
    if (matchResult != null) {
        // 解构正则匹配结果为三个部分:第一个操作数、运算符、第二个操作数
        val (num1, operator, num2) = matchResult.destructured

        // 使用 when 处理不同的运算符
        val result = when (operator) {
            "+" -> num1.toInt() + num2.toInt() // 加法运算
            "-" -> num1.toInt() - num2.toInt() // 减法运算
            "*" -> num1.toInt() * num2.toInt() // 乘法运算
            "/" -> if (num2.toInt() != 0) num1.toInt() / num2.toInt() // 除法运算,检查除数是否为 0
                   else "除数不能为0"
            else -> "未知运算符" // 不支持的运算符
        }

        // 输出结果
        println("结果是:$result")
    } else {
        // 输入格式不正确时的提示
        println("输入格式有误,请检查!")
    }
}

fun main() {
    // 定义一个区间 1..10,表示 [1, 10] 的所有整数
    val range = 1..10

    // 定义一个集合,包含一些特定的值
    val set = setOf(15, 20, 25, 30)

    // 提示用户输入一个数字
    println("请输入一个数字:")
    val input = readLine()?.toIntOrNull() // 获取用户输入并尝试将其转换为整数

    // 检查输入是否为有效数字
    if (input != null) {
        // 使用 when 表达式判断数字所属范围或集合
        when {
            input in range -> println("$input 在区间 $range 中") // 输入在区间内
            input in set -> println("$input 在集合 $set 中") // 输入在集合内
            else -> println("$input 不在区间 $range 和集合 $set 中") // 输入不属于区间和集合
        }
    } else {
        // 输入无效时提示
        println("请输入有效的数字!")
    }
}

好了,本章内容暂且完结,主要介绍一下运算符下一章会开启全新的内容哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值