Code前端首页关于Code前端联系我们

Kotlin编程语法的基础:运算符

terry 2年前 (2023-09-25) 阅读数 47 #后端开发

计算机程序中最小的程序成为一个表达式。每个表达式都可以由两部分组成:操作数和运算符。操作数可以是变量、常量、类、数组、方法等,甚至可以是其他表达式。运算符用于指定语言中单个或多个操作数执行运算的规则。表达式函数之后可以输出的值取决于表达式中涉及的运算符的优先级和操作。 Kotlin语言包含了Java语言的所有运算符特性,并结合了C语言的优点,添加了特殊的运算符逻辑。这些运算符主要有:算术运算符、区间运算符、逻辑运算符、关系运算符、信用运算符、自增和自减运算符等。商人。

  • 一元运算符用于单功能对象,也称为一元运算符,如:++a、!b、i–等。
  • 二元运算符在中间。它有两个操作数,如:a+3、a*b

需要注意的是,Kotlin中没有三元运算符。

基本运算符

基本运算符包括一组在编码项目中常用的运算符,使我们能够编写程序的基本元素。了解基本运算符的使用可以防止一些语法和基本逻辑错误。

赋值运算符(=)

赋值运算a=b表示等号右侧的b开始或保持等号左侧的a。 b 可以是变量、常量、文字或表达式,如:

var IntA:Int = 5
val IntB:Int = 10

IntA = 2 + 1;
IntA = IntB

Kotlin 语言中还有另一种运算符,称为自反算术赋值运算符。它是一个随机运算符,由两个简单运算符组成,包括:“+=”、“-=”、“*=”、“/=”和“%=”。用法如下:

var IntA:Int = 5
val IntB:Int = 10

IntA += IntB // 作用等于 IntA = IntA + IntB
IntA -= IntB // 作用等于 IntA = IntA - IntB
IntA *= IntB // 作用等于 IntA = IntA * IntB
IntA /= IntB // 作用等于 IntA = IntA / IntB
IntA %= IntB // 作用等于 IntA = IntA % IntB

算术运算符

算术运算符用于对数字类型进行运算。 Kotlin语言支持基本的算术运算:加法“+”、减法“-”、乘法“*”、除法“/”、余数“%”,以及自动递增和递减运算,如:

var IntA:Int = 5 + 5  // 10
val IntB:Int = 10 - 2 // 8
val IntC:Int = 3 * 4  // 12
val IntD:Int = 10 / 5 // 2
val IntE:Int = 10 % 3 // 1,除不尽,保留余数
val IntF:Int = 10 / 6 // 1,除不尽,仅保留整数部分

IntA = IntA / 0 // 报错,除数不能为0

auto- 递增和自减运算符(++、-)也是一元运算符。自增运算符“++”表示操作数加1,自减运算符“-”表示操作数减1。操作数可以是整数、浮点数和其他类型的数字,例如:
var intA : Int = 5

intA++ // 等于 intA = intA + 1
println("intA = " + intA)  // 输出 intA = 6

需要注意的是,最有趣的是,自增运算符和自减运算符还分为前自增、后自增、前自减和后自减。放在操作数前面的是前置运算符,放在操作数前面的是后置运算符。
对于后置操作,在前向表达式返回后进行增减操作。如果运算符带有后缀,则先执行自增和自减操作,然后重复表达式。示例:

var intIncA: Int = 5
var intIncB: Int = 5
var intIncC: Int = 5
var intIncD: Int = 5

println(++intIncA) // 先自增, 后返回。 输出 :6
println(--intIncB) // 先自减, 后返回。 输出 :4
println(intIncC--) // 先返回, 后自减。 输出 :5
println(intIncD++) // 先返回, 后自增。 输出 :5

字符串加法 (+)

两个字符串可以组合成一个新字符串。此操作称为字符串连接。在Kotlin语言中,字符串连接可以用“+”来完成。例如:

"hello " + "world" // 等于 "hello world"

连接字符串的功能,两侧都有字符串,但很多情况下我们使用的连接器只有一侧是字符串,另一侧是不同类型。此时系统会自动调用toString方法将其转换为字符串进行拼接。此时,调用了String重载的plus方法。我们将详细介绍运算符重载。 Kotlin中String的源代码如下:
Kotlin编程语法基础:运算符

因此,当字符串与其他类型连接时,我们都使用String类型。 “+”连接器左侧的符号。

var intA : Int = 1
var StringA : String = "String Head "

println(intA + StringA) // 报错,调用的是Int.plus方法
println(StringA + intA) // 输入内容:String Head 1

关系运算符

关系运算符是指用关系操作数对两个操作数或表达式进行运算,结果为真或假。

运算符 名称 示例
小于 a
println(10 == 10) // true
println(1 != 5)   // true
println(1 < 5)    // true
println(1 > 5)    // false
println(4 <= 5)   // true
println(4 >= 5)   // false

注:

算术运算符。
  • 关系经纪人比任务提供者具有更高的优先级。
  • 区间运算符 (a..b)

    区间运算符,顾名思义,可以用来表示两个操作数之间设置的区间。 a..b 通常称为从 a 到 b 的所有数字的集合。在Kotlin的语言中,区间运算符有两种类型:闭区间运算符和开区间运算符。

    • 闭区间运算符:“a..b”a到b范围内的所有值,包括a和b。
    • 半闭区间运算符:“a到b”a到b范围内的所有值,包括a且不存在b。

    范围表达式是通过在 in 和 !in 中添加运算符“..”或 rangeTo 的形式来获得的。 Range 是为可比较类型定义的,但对于原始整数类型它有一个优化的实现。以下是一些使用空格的示例:

    for (i in 1..10) { // 等同于 1 <= i && i <= 10
        println(i)
    }
    
    for (i in 1.rangeTo(10)) {  // 等同于 1 <= i && i <= 10
        println(i)
    }
    
    for (i in 'a'..'z') { // 等同于 'a' <= i && i <= 'z'
        println(i)
    }

    注意:表示在空格内,!in 表示没有。
    整数范围还有一个附加功能:它可以重复。 Kotlin 编译器负责将其转换为 Java 索引 for 循环,而无需任何额外开销。

    for (i in 1..4) print(i) // 输出“1234”
    
    for (i in 4..1) print(i) // 什么都不输出

    运行上面的例子,我们可以看到,如果你只写“..”,这个范围值只是一个序列。如果你想以相反的顺序重复数字怎么办?这也很简单。您可以使用标准库中定义的 downTo 方法:

    for (i in 4 downTo 1) print(i) // 输出“4321”

    是否可以迭代大小不同于 1 的整数?当然没问题,按照分步的方法就可以做到:

    for (i in 1..4 step 2) print(i) // 输出“13”
    
    for (i in 4 downTo 1 step 2) print(i) // 输出“42”

    那么如何创建半封闭间隙呢?您最多可以使用该方法:

    for (i in 1 until 10) {   // i in [1, 10) 排除了 10
         println(i)
    }

    逻辑运算符

    逻辑运算符使用方程来表示判断,并将推理视为方程。这种改变的成功并不取决于人们对符号的解读,而仅仅取决于符号组合的改变。 。与 Java 一样,Kotlin 语言支持三种标准逻辑运算符:逻辑 AND、逻辑 OR 和逻辑非。

    • &&:逻辑与,可以理解为与的意思。
    • ||:逻辑OR,可以理解为OR的意思,即条件可以是两个
    • 之一! :逻辑否定,否定

    在逻辑表达式中,操作数值的不同组合导致整个表达式的值不同。这提供了逻辑函数的值总和的汇总表:

    aba&&ba||bba&&b a|| b
    13a||b♶♶”!假
    truefalseKotlin编程语法基础:运算符

    (大部分都不确定!! )最不确定的!!)Java开发过程中遇到的就是Nul​​lPoint Exception(NPE),很多不可预知的问题都是null异常。 NullPointException是开发中最不常见也是最致命的问题。我们常常需要做出各种无意义的判断来避免NPE。用Kotlin的话说,一切都是一回事,NPE的存在是一个致命的问题。如前所述,在 Kotlin 语言中建议进行 null 预处理,并为此指定了两个运算符: null 运算符“?” 强验证“!!”企业家

    预定义,或可以保留 null (?)

    在 Kotlin 中,类型系统区分引用是否可以保留 null 或不能保留 null。Kotlin 的大多数东西都不能接受 null。例如,基本类型的标准变量不能设置 null:

    var a: String = "abc"
    a = null // 编译错误

    如果要允许 null,可以将变量声明为可空字符串,需要在定义类型后加问号“?”如上例所示,写为 String?:

    var b: String? = "abc"
    b = null // 这样编译没问题

    对于不能接受 null 的类型,我们可以调用 property.property。

    var a: String = "abc"
    var aLength = a.length // 放心调用,a肯定不会为null

    对于同样的操作,我们不能对字符串b进行操作。要使用可能为空的类型,您必须判断它为空。

    空测试(?)

    在 Kotlin 语言中有两种判断对象是否为空的方法。第一种是像Java语言一样使用if-else来测试是否为空;另一种是使用函数Use "?"判断的象征。

    // 在Java语言中我们使用的判空方法。
    if (b != null && b.length > 0) {
        println("String of length ${b.length}")
    } else {
        println("Empty string")
    }
    
    // Kotlin,可空类型的判断
    println("String of length ${b?.length}")

    乍一看差别不大,但是不太安全,而且对于打电话来说非常有用。例如,如果员工 Bob 可能(或可能不)被分配到某个部门,并且可能有另一名员工是部门负责人,则要获取 Bob 的部门负责人的姓名(如果有),请输入:

    bob?.department?.head?.name

    If属性(链接)为空,该回调将返回空。如果你想对非空值进行操作,可以使用let:

    val listWithNulls: List<String?> = listOf("A", null)
    for (item in listWithNulls) {
         item?.let { println(it) } // 输出 A 并忽略 null
    }

    !!操作符

    很多情况下,NullPointerException对我们来说还是有一定意义的,我们必须catch住此异常。那么,Kotlin中的又有空安全的机制存在,我们就必须对null进行强校验。这里,Kotlin给我们提供的操作符为两个引号 “!!”,如:
    var a : String? = null // 必须是可空类型,不然强校验没有意义
    val lenC = a!!.length // 这样做就会报错

    如果需要强验证,并且希望系统抛出NullPointerException,则必须允许定义的Variable接受null,否则强验证就没用了。

    安全类型转换

    如果对象不是目标类型,可能会抛出 ClassCastException。另一种选择是使用安全转换类型,如果转换尝试失败,则返回 null:

    val aInt: Int? = a as? Int

    可空类型的集合

    如果您有可空类型元素的集合,并且希望按“元素不为空”进行过滤,这可以使用方法filterNotNull 来完成。

    val nullableList: List<Int?> = listOf(1, 2, null, 4)
    val intList: List<Int> = nullableList.filterNotNull()

    Elvis 运算符 (?:)

    Elvis 运算符与 Java 语言中的三元表达式非常相似。然而,由于“三元”一词对于许多开发人员来说很难理解,因此经常被错误使用。 。Kotlin完善了三眼表情,这是猫王语音的来源。Kotlin不再支持三目表达。 Elvis 运算符的使用如下:

    <结果> = <表达式1> ?: <表达式2>

    如果表达式 1 为空,则返回表达式 2 的内容,否则返回表达式 1。请注意,如果左侧表达式 1 为空,则计算右侧表达式空的。示例:

    // Elvis操作符获取b字符串的长度,如果b为null则返回-1
    val lenB = b?.length ?: -1
    
    // 等同于逻辑
    val lenA: Int = if (b != null) {
        b.length
    } else {
        -1
    }

    运算符数量

    运算符的优先级使得某些运算符比其他运算符更重要,因此优先级较高的运算符将首先被检查。运算符结合性用于描述相同优先级的运算符在一起时语法规则的组合或关联。在混合语言中,操作者的优先级和配合非常重要。例如:

    2 + 3 - 4 * 5 // 等于 -15

    如果完全从左到右,计算过程如下:

    2 + 3 = 5
    5 - 4 = 1
    1 * 5 = 5

    但实际上是先乘后减,所以实际的计算过程是:

    2 + 3 = 5
    4 * 5 = 20
    5 - 20 = -15

    类似情况。我们做数学中同样的事情:首先计算右括号,然后先乘除,即加法和减法。Kotlin的语言也有优先和合作。这里我们总结所有运算符如下:运算符

    关联性
    1(), []‶ ), -(负 ), ~, ++, – 从右到左
    3 *, /, % 从左到右
    4+(加),-(减)
    5,>>>从左到右
    6,>=从左到右
    7==♶=♶右
    8&(按位与)从左到右
    9 ^左起到右
    10|
    7
    11
    从左到右
    12||从左到右
    13?:右向左
    13=, +=, -=, /=, %=, &=, |=, ^=, ~=, =, >>>=从右到左

    用户太多

    已定义运算符操作数 事先它只能是一个基本的数据类型,实际上我们构建的很多东西。也需要同样的手术。重写运算符就是为现有运算符赋予多种含义,使得同一个运算符对不同类型的数据进行操作,产生不同类型的行为。
    运算符重载是C++语言支持的功能。然而,Java 中不再支持此功能,这对于高级科学工作来说非常烦人。Kotlin的语言再次支持这一功能。与相应的赋值运算符不同,我们可以指定 /、==、-、+、*、%、、! 、&、|、^等逻辑函数的运算符。要重载运算符,必​​须删除相应的过程。以下是“+”运算符的定义:

    public operator fun plus(other: Byte): Float

    这里,我们可以看到重载运算符的主要原因是为了运行方法。执行过程中,指定的过程会转换为对action方法的调用,并将要执行的对象转换为operator方法的true参数。然后根据参数的类型决定应该调用自定义函数。之后,Kotlin将调用相应的符号事件并继续进行样式。因为 Float 类型是为“+”运算符定义的:
    Kotlin编程语法基础:运算符

    重载一元运算符

    一元前缀运算符

    表达式 方法
    11 +a a .unaryPlus( )
    -aa.unaryMinus()
    !aa.not()

    这个表表示当编译器做+a时,例如:

    1. 定义类型a和令为 T。
    2. 查找一个无参数 unaryPlus() 函数,其带有接收者 T 的运算符修饰符,即成员函数或扩展函数。
    3. 减少函数丢失或不明确时出现的编译错误。
    4. 如果有一个函数,其返回类型为R,则表达式+a的类型为R。 )
    a--a.dec()

    inc() 和 dec () 函数必须返回使用 ++ 或 – 运算符赋予变量的值。他们不应修改 inc() 或 dec() 对象。
    编译器按照以下步骤分析操作符的后缀形式,例如 a++:

    1. 对于 T 类型的接收者,定义类型 a 并将其设为 T。
    2. 检查 a 的返回类型是否正确该函数是 T 的子类。

    计算项的步骤为:

    1. 将 a 的初始值存储到暂存器 a0 中,
    2. 将 a.inc() 的结果指向 a,
    3. 返回 a0 作为表达式 的结果。
    4. 对于a-,过程完全相同。

    后缀++a和-a的处理方式相同,步骤如下:

    1. 将a.inc()的结果设置为a,
    2. 返回新值as。反应的结果。

    二元运算符

    算术运算符

    表达式 转换方法
    a + b♶♶ ba.减 (B) A * b
    a.times (b)
    a / ba.div (b)
    A % ba.mod (b) ” a.rangeTo(b)

    For对于该表中的操作,编译器只是将翻译后的表达式转换为列。请注意,从 Kotlin 1.1 开始支持 rem 运算符。 Kotlin 1.0 使用 mod 运算符,而 Kotlin 1.1 中未使用该运算符。

    用户“In”

    表达式 转换方法
    a 到 bb.with(a) !b.with(a)

    对于“在和!”中,过程是一样的,只是参数的顺序相反。

    输入索引运算符

    语言 转换方法
    a[i]a.get(i)
    13a .get(i , j )
    a[i_1 , … , i_n]a.get(i_1, … , i_n)
    a[i]=ba.set(i, b) i,j]=ba.set( i, j, b)
    a[i_1, … , i_n]=ba.set(i_1,… ,o_n,b) 方括号被解释为使用适当的数字接收和设置的调用的论点。

    调用运算符

    表达式 转换方法
    a(i)a.invoke(i)♽,
    13 a.invoke(i , j)
    a(i_1 , … , i_n)a.invoke(i_1, …, i_n)

    括号被解释为使用适当数量的参数进行调用。

    通用函数

    表达式 转换方法
    a += ba.plusAssign(b)=
    a += b a.plusAssign♽(b) a。 minusAssign(b)
    a *= bta.timesassIGN (b)
    A /= ba.divassign (b)
    ♸ ♸ .modassign (b)

    对于赋值 对于赋值,例如 a += b,编译器执行以下步骤:

    1. 如果右列中存在该赋值
    2. 如果相应的二元函数(即 plusAssign() plus())也存在存在,则报告错误(含糊)。
    3. 确保返回类型为Unit,否则会出错。
    4. 为 a.plusAssign(b) 生成代码
    5. 否则,尝试为 a = a + b 生成代码(存在类型检查:类型 a + b 必须是 a 的子类型)。

    注:提名不代表Kotlin。

    等式和不等式运算符

    表达式转换
    a == ba? .EQUE (b)?: (B === null)
    a! = b!(a?.equals(b) ?: (b === null))

    == 运算符有点特殊:它被解释为过滤掉 null 值含义的复杂表达式。 null == null 始终为 true,对于非空 x,x == null 始终为 false,除非调用 x.equals()。
    注意:=== 和 !==(身份检查)不能被覆盖。

    比较运算符

    表达式转换方法
    a > ba.compareTo(b) > 0❀ a .compareTo(b)
    a >= ba.compareTo(b) >= 0
    a > 相同)
    和(位)按位 SY 或(位)
    xor(位)按位互斥OR
    inv()按位求反

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门