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 教程。