Kotlin 运算符
最后修改于 2024 年 1 月 29 日
在本文中,我们将介绍 Kotlin 运算符。 我们将展示如何使用运算符创建表达式。
一个运算符是一个特殊的符号,它指示要执行某个特定的过程。 编程语言中的运算符来自数学。 程序员处理数据。 运算符用于处理数据。一个操作数是运算符的输入(参数)之一。
表达式由操作数和运算符构成。 表达式的运算符指示要对操作数应用哪些操作。 表达式中运算符的求值顺序由运算符的优先级和结合性决定。
一个运算符通常有一个或两个操作数。 那些只使用一个操作符的操作符被称为一元运算符。 那些使用两个操作数的被称为二元运算符。
某些运算符可能在不同的上下文中使用。 例如,+
运算符可以在不同的情况下使用:它添加数字、连接字符串或指示数字的符号。 我们说该运算符被重载。
Kotlin 符号运算符
有两个符号运算符:+
和 -
。它们用于表示或改变值的符号。
package com.zetcode fun main() { println(2) println(+2) println(-2) }
+
和 -
符号表示值的符号。 加号可用于表示我们有一个正数。 它可以被省略,并且在大多数情况下都是这样做的。
package com.zetcode fun main() { val a = 1 println(-a) println(-(-a)) }
减号会改变值的符号。
Kotlin 赋值运算符
赋值运算符 =
将一个值赋给一个变量。 变量是值的占位符。 在数学中,= 运算符具有不同的含义。 在一个等式中,=
运算符是一个相等运算符。 等式的左边等于右边。
val x = 1
在这里,我们将一个数字赋给 x
变量。
x = x + 1
这个表达式在数学上没有意义,但在编程中是合法的。 表达式将 1 加到 x
变量。 右边等于 2,2 被分配给 x
。
3 = x
此代码行导致语法错误。 我们不能将值赋给字面量。
Kotlin 增强赋值运算符
增强赋值运算符是包含两个运算符的简写运算符。 增强赋值运算符在其他编程语言中也称为复合赋值运算符。
a = a + 3 a += 3
+=
复合运算符是这些简写运算符之一。上面的两个表达式是相等的。将值 3 加到 a 变量上。
Kotlin 增强赋值运算符是
+= -= *= /= %=
以下示例使用两个复合运算符。
package com.zetcode fun main() { var a = 1 a = a + 1 println(a) a += 5 println(a) a *= 3 println(a) }
我们使用 +=
和 *=
复合运算符。
var a = 1 a = a + 1
a
变量初始化为 1。 使用非简写符号将值 1 添加到变量中。
a += 5
使用 +=
复合运算符,我们将 5 加到 a 变量。 语句等于 a = a + 5
。
a *= 3
使用 *=
运算符,a 乘以 3。语句等于 a = a * 3
。
2 7 21
Kotlin 连接字符串
在 Kotlin 中,+ 运算符也用于连接字符串。
package com.zetcode fun main() { println("Return " + "of " + "the king.") println("Return".plus(" of").plus(" the king.")) }
我们将三个字符串连接在一起。
println("Return " + "of " + "the king.")
字符串与 +
运算符连接。
println("Return".plus(" of").plus(" the king."))
连接字符串的另一种方法是 plus
方法。
Kotlin 递增和递减运算符
将一个值递增或递减一是在编程中常见的任务。 Kotlin 有两个方便的运算符用于此:++
和 --
。
x++ x = x + 1 ... y-- y = y - 1
以上两对表达式执行相同的操作。
package com.zetcode fun main() { var x = 6 x++ x++ println(x) x-- println(x) }
在上面的示例中,我们演示了这两个运算符的用法。
int x = 6 x++ x++
我们将 x
变量初始化为 6。然后我们对 x
加一两次。现在变量的值是 8。
x--
我们使用了递减运算符。现在变量的值是 7。
Kotlin 算术运算符
以下是 Kotlin 中算术运算符的表。
符号 | 名称 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 余数 |
下面的示例展示了算术运算。
package com.zetcode fun main() { val a = 10 val b = 11 val c = 12 val add = a + b + c val sb = c - a val mult = a * b val div = c / 3 val rem = c % a println(add) println(sb) println(mult) println(div) println(rem) }
在前面的示例中,我们使用了加法、减法、乘法、除法和取余运算。这些都与数学中的一样熟悉。
val rem = c % a
%
运算符称为余数或模运算符。它用于找出两个数相除的余数。例如,9 % 4
,9 模 4 等于 1,因为 4 能整除 9 两次,余数为 1。
整数除法和浮点除法之间存在区别。
package com.zetcode fun main() { val c = 5 / 2 println(c) val d = 5 / 2.0 println(d) }
在前面的示例中,我们对两个数进行了除法运算。
val c = 5 / 2
在这段代码中,我们进行了整数除法。除法运算的返回值是整数。当我们对两个整数进行除法时,结果是一个整数。
val d = 5 / 2.0
如果其中一个值是双精度浮点数或单精度浮点数,我们就执行浮点数除法。在本例中,第二个操作数是双精度浮点数,所以结果也是双精度浮点数。
2 2.5
我们看到了程序的输出。
Kotlin 布尔运算符
在 Kotlin 中,我们有三个逻辑运算符。
符号 | 名称 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
布尔运算符也称为逻辑运算符。
package com.zetcode fun main() { val x = 3 val y = 8 println(x == y) println(y > x) if (y > x) { println("y is greater than x") } }
许多表达式会产生布尔值。例如,布尔值用于条件语句。
println(x == y) println(y > x)
关系运算符始终产生布尔值。这两行打印 false 和 true。
if (y > x) { println("y is greater than x") }
只有当括号内的条件满足时,才会执行 if
语句的主体。y > x
返回 true,因此消息 "y is greater than x" 会打印到终端。
true
和 false
关键字表示 Kotlin 中的布尔字面量。
package com.zetcode fun main() { val a = true && true val b = true && false val c = false && true val d = false && false println(a) println(b) println(c) println(d) }
代码示例展示了逻辑与 (&&
) 运算符。仅当两个操作数都为 true 时,它才为 true。
true false false false
只有一个表达式的结果为 true。
如果任何一个操作数为真,逻辑或 (||
) 运算符的计算结果为真。
package com.zetcode fun main() { val a = true || true val b = true || false val c = false || true val d = false || false println(a) println(b) println(c) println(d) }
如果运算符的任一边为 true,则操作的结果为 true。
true true true false
四分之三的表达式结果为 true。
否定运算符 !
将 true 变为 false,将 false 变为 true。
package com.zetcode fun main() { println(! true) println(! false) println(! (4 < 3)) }
该示例展示了否定运算符的实际应用。
false true true
Kotlin 比较运算符
比较运算符用于比较值。 这些运算符始终产生布尔值。
符号 | 含义 |
---|---|
< | 小于 |
<= | 小于或等于 |
> | 大于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
比较运算符也称为关系运算符。
package com.zetcode fun main() { println(3 < 4); println(3 == 4); println(4 >= 3); println(4 != 3); }
在代码示例中,我们有四个表达式。 这些表达式比较整数值。 每个表达式的结果是真或假。 在 Kotlin 中,我们使用 ==
来比较数字。 (一些语言(如 Ada、Visual Basic 或 Pascal)使用 =
来比较数字。)
Kotlin 位运算
与 Java 不同,Kotlin 中没有位运算符。 Kotlin 有执行位运算的命名函数。
- shl(位) – 左移 (Java 的 <<)
- shr(位) – 右移 (Java 的 >>)
- ushr(位) – 无符号右移 (Java 的 >>>)
- and(位) – 位与
- or(位) – 位或
- xor(位) – 位异或
- inv() – 位取反
这些函数仅适用于 Int
和 Long
类型。
位与运算在两个数字之间执行逐位比较。 只有当操作数中对应的位都为 1 时,位位置的结果才为 1。
00110 & 00011 = 00010
第一个数字是 6 的二进制表示法,第二个是 3,结果是 2。
println(6 and 3) // prints 2 println(3 and 6) // prints 2
位或运算在两个数字之间执行逐位比较。 如果操作数中对应的位中有任何一个为 1,则位位置的结果为 1。
00110 | 00011 = 00111
结果是 00110
或十进制的 7。
println(6 or 3) // prints 7 println(3 or 6) // prints 7
Kotlin is 运算符
要在运行时检查一个对象是否符合给定的类型,我们可以使用 is
运算符或其否定形式 !is
。
package com.zetcode open class Base class Derived : Base() fun main() { val b = Base() val d = Derived() println(d is Base) println(b is Derived) println(d is Any) }
在这个例子中,我们有两个类:一个基类和一个从基类派生的类。
println(d is Base)
此行检查变量 d
是否指向 Base
类的实例。 由于 Derived
类继承自 Base
类,因此它也是 Base
类的实例。 该行打印 true。
println(b is Derived)
b
对象不是 Derived
类的实例。 此行打印 false。
println(d is Any)
每个类都有 Any
作为超类。 因此,d
对象也是 Any
类的实例。
true false true
Kotlin lambda 运算符
Kotlin 有 lambda 运算符 (->
)。 它分隔 lambda 表达式的参数和主体。
package com.zetcode import java.util.Arrays fun main() { val words = arrayOf("kind", "massive", "atom", "car", "blue") Arrays.sort(words) { s1: String, s2: String -> s1.compareTo(s2) } println(Arrays.toString(words)) }
在这个例子中,我们定义了一个字符串数组。 该数组使用 Arrays.sort
方法和 lambda 表达式进行排序。
[atom, blue, car, kind, massive]
Kotlin 双冒号运算符
双冒号运算符 (::) 用于创建类或函数引用。
package com.zetcode fun main() { val c = String::class c.supertypes.forEach { e -> println(e) } val words = listOf("car", "forest", "Bible") println(words.map(String::length)) }
在代码示例中,我们使用双冒号运算符创建对类和函数的引用。
val c = String::class c.supertypes.forEach { e -> println(e) }
使用双冒号运算符,我们引用 String
类。 我们打印它的所有祖先。
val words = listOf("car", "forest", "Bible") println(words.map(String::length))
在这里,我们对列表中的所有单词应用 length
函数。
kotlin.Comparable<kotlin.String> kotlin.CharSequence java.io.Serializable kotlin.Any [3, 6, 5]
Kotlin 范围运算符
Kotlin 范围运算符 (..) 允许创建值范围。
package com.zetcode fun main() { for (i in 1..14 step 3) { println(i) } }
该示例使用范围运算符在 for 循环中创建一个整数序列。
1 4 7 10 13
非空断言运算符
非空断言运算符 (!!) 将任何值转换为非空类型,如果该值为 null,则抛出异常。
package com.zetcode fun main() { // val words = listOf("forest", null, "Bible", "sky") val words = listOf("forest", "Bible", "sky") var nOfChars: Int = 0 for (word in words) { val n = word!!.length nOfChars += n } println("There are ${nOfChars} characters in the list") }
该示例计算单词列表中字符的数量。 如果列表包含空值,则抛出 KotlinNullPointerException
。
Kotlin Elvis 运算符
Elvis 运算符 ?: 如果其第一个表达式不为 null,则返回第一个表达式,否则返回第二个表达式。
package com.zetcode fun main() { val words = listOf("forest", null, "Bible", "sky") for (word in words) { val n = word?.length ?: 0 println("${word} has ${n} letters") } }
在示例中,我们使用 Elvis 运算符检查列表中的空值。
val n = word?.length ?: 0
如果变量 word
包含 null,则 ?: 返回 0。
forest has 6 letters null has 0 letters Bible has 5 letters sky has 3 letters
Kotlin 空安全运算符
Kotlin 的空安全运算符 ?.
提供了一个安全的方法调用——仅当对象不为 null 时才调用一个方法。
package com.zetcode fun main() { val words = listOf("forest", null, "Bible", "sky") for (word in words) { println(word?.toUpperCase()) }
在这个例子中,我们将字符串转换为大写; 我们使用空安全运算符。 对于 null 值,不调用该方法。
FOREST null BIBLE SKY
Kotlin 索引访问运算符
Kotlin 索引访问运算符用于从数组中获取值。
package com.zetcode fun main() { val nums = arrayOf(3, 2, 1, 4, 5, 6, 7) val v1 = nums[0] val v2 = nums[3] println(v1) println(v2) }
在示例中,我们使用 []
运算符从数组中检索两个值。
Kotlin 引用相等运算符
Kotlin 区分结构相等和引用相等。 结构相等运算符 (==
) 检查两个对象是否具有相同的内容。 引用相等运算符 (===
) 检查变量是否指向内存中的同一对象。
package com.zetcode data class Item(var name: String, var color: String) fun main() { val i1 = Item("coin", "brown") val i2 = i1 println("Output: ${i1 == i2}") println("Output: ${i1 === i2}") val i3 = Item("coin", "brown") val i4 = Item("coin", "brown") println("Output: ${i3 == i4}") println("Output: ${i3 === i4}") }
该示例演示了 ==
和 ===
运算符之间的区别。
Output: true Output: true Output: true Output: false
Kotlin 运算符优先级
运算符优先级告诉我们哪些运算符首先被求值。优先级级别对于避免表达式中的歧义是必需的。
以下表达式的结果是 28 还是 40?
3 + 5 * 5
就像在数学中一样,乘法运算符的优先级高于加法运算符。所以结果是 28。
(3 + 5) * 5
要更改求值顺序,我们可以使用括号。括号内的表达式总是首先被求值。上述表达式的结果是 40。
package com.zetcode fun main() { println(3 + 5 * 5) println((3 + 5) * 5) println(!true or true) println(!(true or true)) }
在这段代码示例中,我们展示了几个表达式。每个表达式的结果取决于优先级级别。
println(3 + 5 * 5)
此行打印 28。乘法运算符的优先级高于加法。 首先,计算 5 * 5
的乘积,然后加上 3。
println((3 + 5) * 5)
可以使用圆括号更改表达式的求值。 在这种情况下,3 + 5
被求值,然后该值乘以 5。 此行打印 40。
println(!true or true)
在这种情况下,否定运算符的优先级高于按位或。 首先,初始的真值被否定为假,然后 |
运算符将假和真组合起来,最后得到真。
28 40 true false
结合性规则
有时优先级不足以确定表达式的结果。还有另一个规则称为结合性。运算符的结合性决定了具有相同优先级级别的运算符的求值顺序。
9 / 3 * 3
这个表达式的结果是 9 还是 1?乘法、除法和模运算符是从左到右结合的。所以表达式的求值方式是:(9 / 3) * 3
结果是 9。
算术、布尔和关系运算符是从左到右关联的。 三元运算符、递增、递减、一元加和减、否定、按位取反、类型转换、对象创建运算符是右到左关联的。
package com.zetcode fun main() { var j = 0 j *= 3 + 1 println(j) }
在这个例子中,我们用结合律规则确定表达式的结果。
var j = 0 j *= 3 + 1
增强赋值运算符是右到左关联的。 我们可能期望结果为 1。 但实际结果是 0。 由于结合性。 右边的表达式先求值,然后应用复合赋值运算符。
计算质数
在下面的例子中,我们将计算质数。
package com.zetcode fun main() { val nums = intArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28) print("Prime numbers: ") for (num in nums) { if (num == 0 || num == 1) { continue } if (num == 2 || num == 3) { print(num.toString() + " ") continue } var i = Math.sqrt(num.toDouble()).toInt() var isPrime = true while (i > 1) { if (num % i == 0) { isPrime = false } i-- } if (isPrime) { print(num.toString() + " ") } } print('\n') }
在上面的例子中,我们处理几个运算符。 素数(或质数)是一个自然数,它恰好有两个不同的自然数除数:1 和它本身。 我们取一个数字并将其除以从 1 到所选数字的数字。 实际上,我们不必尝试所有较小的数字; 我们可以除以小于所选数字的平方根的数字。 公式将起作用。 我们使用余数除法运算符。
val nums = intArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28)
我们将计算这些数字的素数。
if (num == 0 || num == 1) { continue }
值 0 和 1 不被认为是素数。
if (num == 2 || num == 3) { print(num.toString() + " ") continue }
我们跳过对 2 和 3 的计算。它们是素数。 注意等式和条件或运算符的用法。 ==
的优先级高于 ||
运算符。 所以我们不需要使用括号。
var i = Math.sqrt(num.toDouble()).toInt()
如果我们只尝试小于目标数字的平方根的数字,那就可以了。
while (i > 1) { ... i-- }
这是一个 while 循环。 i
是该数字的计算平方根。 我们使用递减运算符将 i
减 1。 当 i 小于 1 时,我们终止循环。 例如,我们有数字 9。 9 的平方根是 3。 我们将 9 除以 3 和 2。 这足以满足我们的计算。
if (num % i == 0) { isPrime = false }
如果求余运算符对于任何 i 值返回 0,则目标数字不是质数。
来源
在本文中,我们介绍了 Kotlin 运算符。
作者
列出 所有 Kotlin 教程。