在本教程中,我们将介绍 Kotlin 运算符。 我们展示了如何使用运算符创建表达式。
运算符是特殊符号,表示已执行某个过程。 编程语言的运算符来自数学。 程序员处理数据。 运算符用于处理数据。 操作数是运算符的输入(参数)之一。
表达式是根据操作数和运算符构造的。 表达式的运算符指示将哪些运算应用于操作数。 表达式中运算符的求值顺序由运算符的优先级和关联性确定。
一个运算符通常有一个或两个操作数。 那些仅使用一个操作数的运算符称为一元运算符。 那些使用两个操作数的对象称为二进制运算符。
某些运算符可以在不同的上下文中使用。 例如,+
运算符可以在不同的情况下使用:它添加数字,连接字符串或指示数字的符号。 我们说运算符是重载。
Kotlin 标志运算符
有两个符号运算符:+
和-
。 它们用于指示或更改值的符号。
KotlinSignOperatorsEx.kt
package com.zetcode
fun main(args: Array<String>) {
println(2)
println(+2)
println(-2)
}
+
和-
符号指示值的符号。 加号可用于表示我们有一个正数。 可以省略它,并且在大多数情况下可以这样做。
KotlinMinusSignEx.kt
package com.zetcode
fun main(args: Array<String>) {
val a = 1
println(-a)
println(-(-a))
}
减号更改值的符号。
Kotlin 赋值运算符
赋值运算符=
将值赋给变量。 变量是值的占位符。 在数学中,=运算符具有不同的含义。 在等式中,=
运算符是一个相等运算符。 等式的左边等于右边的等式。
val x = 1
在这里,我们为x
变量分配一个数字。
x = x + 1
这个表达式在数学上没有意义,但是在编程中是合法的。 该表达式将x
变量加 1。 右边等于 2,并且 2 分配给x
。
3 = x
此代码行导致语法错误。 我们无法为文字分配值。
Kotlin 扩展赋值运算子
扩展赋值运算符是由两个运算符组成的速记运算符。 增强的赋值运算符在其他编程语言中也称为复合赋值运算符。
a = a + 3
a += 3
+=
复合运算符是这些速记运算符之一。 以上两个表达式相等。 将值 3 添加到变量 a 中。
Kotlin 扩展分配运算符为:
+= -= *= /= %=
下面的示例使用两个复合运算符。
KotlinAugmentedAssignmentOperatorsEx.kt
package com.zetcode
fun main(args: Array<String>) {
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 中,+运算符还用于连接字符串。
KotlinConcatenateStringsEx.kt
package com.zetcode
fun main(args: Array<String>) {
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
上面两对表达式的作用相同。
KotlinIncDecEx.kt
package com.zetcode
fun main(args: Array<String>) {
var x = 6
x++
x++
println(x)
x--
println(x)
}
在上面的示例中,我们演示了两个运算符的用法。
int x = 6
x++
x++
将x
变量初始化为 6。然后将x
递增两次。 现在变量等于 8。
x--
我们使用减量运算符。 现在变量等于 7。
Kotlin 算术运算符
下表是 Kotlin 中的算术运算符表。
符号 | 名称 |
---|---|
+ |
加法 |
- |
减法 |
* |
乘法 |
/ |
乘法 |
% |
余数 |
以下示例显示了算术运算。
KotlinArithmeticOperatorsEx.kt
package com.zetcode
fun main(args: Array<String>) {
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。
整数除法和浮点除法之间有区别。
KotlinDivisionEx.kt
package com.zetcode
fun main(args: Array<String>) {
val c = 5 / 2
println(c)
val d = 5 / 2.0
println(d)
}
在前面的示例中,我们将两个数字相除。
val c = 5 / 2
在这段代码中,我们完成了整数除法。 除法运算的返回值为整数。 当我们将两个整数相除时,结果是一个整数。
val d = 5 / 2.0
如果值之一是 double 或 float,则执行浮点除法。 在我们的例子中,第二个操作数是双精度数,因此结果是双精度数。
2
2.5
我们看到了程序的结果。
Kotlin 布尔运算符
在 Kotlin 中,我们有三个逻辑运算符。
符号 | 名称 |
---|---|
&& |
逻辑与 |
|| |
逻辑或 |
! |
否定 |
布尔运算符也称为逻辑运算符。
KotlinBooleanExpEx.kt
package com.zetcode
fun main(args: Array<String>) {
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 大于 x”被打印到终端。
true
和false
关键字表示 Kotlin 中的布尔文字。
KotlinAndOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
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。
如果两个操作数中的任何一个为 true,则逻辑或(||
)运算符的计算结果为 true。
KotlinOrOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
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
四个表达式中的三个表示为 true。
否定运算符!
将 true 设为 false,并将 false 设为 false。
KotlinNegationEx.kt
package com.zetcode
fun main(args: Array<String>) {
println(! true)
println(! false)
println(! (4 < 3))
}
该示例显示了否定运算符的作用。
false
true
true
这是程序的输出。
Kotlin 比较运算符
比较运算符用于比较值。 这些运算符总是产生布尔值。
符号 | 含义 |
---|---|
< |
小于 |
<= |
小于或等于 |
> |
大于 |
>= |
大于或等于 |
== |
等于 |
!= |
不等于 |
比较运算符也称为关系运算符。
KotlinComparisonOperatorsEx.kt
package com.zetcode
fun main(args: Array<String>) {
println(3 < 4);
println(3 == 4);
println(4 >= 3);
println(4 != 3);
}
在代码示例中,我们有四个表达式。 这些表达式比较整数值。 每个表达式的结果为 true 或 false。 在 Kotlin 中,我们使用==
比较数字。 (某些语言(例如 Ada,Visual Basic 或 Pascal)使用=
比较数字。)
Kotlin 按位运算符
与 Java 不同,Kotlin 中没有按位运算符。 Kotlin 已经命名了执行按位运算的函数。
- shl(bits)–有符号左移(Java 的< <)
- shr(bits)–有符号右移(Java 的> >)
- ushr(bits)–无符号右移(Java 的> > >)
- 和(位)–按位与
- 或(位)–按位或
- xor(bits)–按位异或
- 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
。
KotlinIsOperatorEx.kt
package com.zetcode
open class Base
class Derived : Base()
fun main(args: Array<String>) {
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
类的实例。 该行打印正确。
println(b is Derived)
b
对象不是Derived
类的实例。 该行显示 false。
println(d is Any)
每个类都有Any
作为超类。 因此,d
对象也是Any
类的实例。
true
false
true
这是程序的输出。
Kotlin Lambda 运算符
Kotlin 具有 lambda 运算符(->
)。 它分隔了 lambda 表达式的参数和主体。
KotlinLambdaOperatorEx.kt
package com.zetcode
import java.util.Arrays
fun main(args: Array<String>) {
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 双冒号运算符
双冒号运算符(::)用于创建类或函数引用。
KotlinDoubleColonOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
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 范围运算符(..)允许创建值范围。
KotlinRanageOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
for (i in 1..14 step 3) {
println(i)
}
}
该示例使用范围运算符在 for 循环中创建整数序列。
1
4
7
10
13
这是输出。
非空断言运算符
非 null 断言运算符(!!)会将任何值转换为非 null 类型,并且如果该值为 null 则引发异常。
KotlinNullAssertionOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
// 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,则返回其第一个表达式,否则返回第二个表达式。
KotlinElvisOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
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 安全操作符?.
提供了安全的方法调用-仅当对象不为 null 时才调用方法。
KotlinNullSafetyOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
val words = listOf("forest", null, "Bible", "sky")
for (word in words) {
println(word?.toUpperCase())
}
在示例中,我们将字符串转换为大写; 我们使用 null 安全运算符。 对于 null 值,不调用该方法。
FOREST
null
BIBLE
SKY
这是输出。
Kotlin 索引访问运算符
Kotlin 索引访问运算符用于从数组获取值。
KotlinIndexAccessOperatorEx.kt
package com.zetcode
fun main(args: Array<String>) {
val nums = arrayOf(3, 2, 1, 4, 5, 6, 7)
val v1 = nums[0]
val v2 = nums[3]
println(v1)
println(v2)
}
在示例中,我们使用[]
运算符从数组中检索两个值。
Kotlin 引用相等运算符
Kotlin 区分结构相等和引用相等。 结构相等运算符(==
)检查两个对象是否具有相同的内容。 引用相等运算符(===
)检查变量是否指向内存中的同一对象。
KotlinreferentialEqualityOperatorEx.kt
package com.zetcode
data class Item(var name: String, var color: String)
fun main(args: Array<String>) {
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。
KotlinOperatorPrecedenceEx.kt
package com.zetcode
fun main(args: Array<String>) {
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)
在这种情况下,求反运算符的优先级高于按位或。 首先,将初始 true 值取反为 false,然后|
运算符将 false 和 true 组合在一起,最后给出 true。
28
40
true
false
这是示例输出。
关联规则
有时,优先级不能令人满意地确定表达式的结果。 还有另一个规则称为关联性。 运算符的关联性决定了具有相同优先级的运算符的评估顺序。
9 / 3 * 3
此表达式的结果是 9 还是 1? 乘法,删除和模运算符从左到右关联。 因此,该表达式的计算方式为:(9 / 3) * 3
,结果为 9。
算术运算符,布尔运算符和关系运算符从左到右关联。 三元运算符,递增,递减,一元正负,取反,按位不,类型强制转换,对象创建运算符从右到左关联。
KotlinAssociativityRuleEx.kt
package com.zetcode
fun main(args: Array<String>) {
var j = 0
j *= 3 + 1
println(j)
}
在示例中,我们的关联规则确定表达式的结果。
var j = 0
j *= 3 + 1
增强的赋值运算符从右到左关联。 我们可能期望结果为 1。但是实际结果为 0。由于有关联性。 首先评估右边的表达式,然后应用复合赋值运算符。
计算素数
在下面的示例中,我们将计算素数。
KotlinPrimeNumbersEx.kt
package com.zetcode
fun main(args: Array<String>) {
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,则说明该数字不是质数。