文章结构:
- 一元操作符
- 前缀操作符
- 递增和递减操作符
- 二元操作符
- 算术运算操作符
- 自定义重载的“+”运算符
- in 操作符
- 索引访问操作符
- 调用操作符
- 计算并赋值操作符
- 相等与不等操作符
- Elvis 操作符
?:
- 比较操作符
- infix 函数,自定义中缀操作符
一元操作符
前缀操作符
- 前缀
+
,正
+a
a.unaryPlus()
- 前缀
-
,负
-a
a.unaryMinus()
- 前缀
!
,取否
!isOk
fun main(args: Array<String>) {
var a = 7
println(a) // 7
println(+a) // 7
println(-a) // -7
println(a.unaryPlus()) // 7
println(a.unaryMinus()) // -7
a = -5
println(a) // -5
println(+a) // -5
println(-a) // 5
println(a.unaryPlus()) // -5
println(a.unaryMinus()) // 5
var isOk = true
println(!isOk) // false
println(isOk) // true
isOk = false
println(!isOk) // true
println(isOk) // false
}
// 重载一元操作符:
// 1. 声明数据类
data class Point(val x:Int, val y:Int)
// 2. 重载一元操作符:operator修饰符 修饰重载操作符函数
// 使用关键字operator实现重载 函数unaryMinus()
operator fun Point.unaryMinus() = Point(-x, -y)
// 3. 测试
fun test() {
val p = Point(1, -5)
val px = p.unaryMinus()
println(p) // 输出:Point(x=1, y=-5)
println(px) // 输出:Point(x=-1, y=5)
println(-p) // 输出:Point(x=-1, y=5)
}
递增和递减操作符
inc()
和dec()
函数有返回值,它用于赋值给使用++
或--
操作的变量。
前缀和后缀的表达式(++
或--
)的返回值是不同的:
fun testF() {
println("a++ :")
var a = 5
println(a++) // 输出:5
println(a) // 输出:6
println(a.inc()) // 输出:7
println(a) // 输出:6
println("++a :")
a = 5
println(++a) // 输出:6
println(a) // 输出:6
println(a.inc()) // 输出:7
println(a) // 输出:6
println("a-- :")
a = 5
println(a--) // 输出:5
println(a) // 输出:4
println(a.dec()) // 输出:3
println(a) // 输出:4
println("--a :")
a = 5
println(--a) // 输出:4
println(a) // 输出:4
println(a.dec()) // 输出:3
println(a) // 输出:4
}
二元操作符
算术运算操作符
算术运算符: + - * / % ..
fun testArithmeticF() {
val a = 10
val b = 6
println(a+b) // 输出:16
println(a.plus(b)) // 输出:16
println(a-b) // 输出:4
println(a.minus(b)) // 输出:4
println(a*b) // 输出:60
println(a.times(b)) // 输出:60
println(a/b) // 输出:1
println(a.div(b)) // 输出:1
println(a%b) // 输出:4
println(a.mod(b)) // 输出:4
println(a.rem(b)) // 输出:4
println(a..b) // 输出:10..6
println(a.rangeTo(b)) // 输出:10..6
println(a.downTo(b)) // 输出:10 downTo 6 step 1
println(a downTo b) // 输出:10 downTo 6 step 1
println(b..a) // 输出:6..10
println(b.rangeTo(a)) // 输出:6..10
}
自定义重载的“+”、“-”运算符
// 重载加法和减法运算符:
data class Counter(var c: Int) // 声明一个类
operator fun Counter.plus(inc: Int) : Counter {
// 重载加法运算符,实现 c加上inc
return Counter(c + inc)
}
// 重载减法运算符,实现 c减去dec
operator fun Counter.minus(dec: Int) = Counter(c - dec)
fun textOverwriteF(): Unit {
val count = Counter(5) // 声明一个count对象,初始化 c=5
val a = count + 9 // 调用重载的加法运算符
val b = count -3 // 调用重载的减法运算符
println(a) // 输出:Counter(c=14)
println(b) // 输出:Counter(c=2)
}
in 操作符
in
操作符等价于 contains()
函数。
fun testIn(): Unit {
val arr = arrayOf(1,2,3,4,5)
val x = 3
println(x in arr) // 输出:true
println(x !in arr) // 输出:false
println(arr.contains(x)) // 输出:true
println(!arr.contains(x)) // 输出:false
println(9 in arr) // 输出:false
println(arr.contains(12)) // 输出:false
}
索引访问操作符
索引访问操作符[]
相当于 带参数的 get
、set
函数:
fun testIndex(): Unit {
val arr = arrayOf(1,2,3)
val index = 1
println(arr[index]) // 输出:2
println(arr.get(index)) // 输出:2
arr[index] = 9
println(arr[index]) // 输出:9
arr.set(index, 20)
println(arr[index]) // 输出:20
}
调用操作符
调用操作符()
相当于 invoke()
函数。
// 使用表达式声明 sumF2()函数,{}表示一个Lambda表达式
fun sumF2(x: Int, y: Int) = { x + y } // ⚠️ x+y 与 { x+y } 的区别
fun main(args: Array<String>) {
println(sumF2(5,15)) // 输出:() -> kotlin.Int,
println(sumF2(5,15).invoke()) // 输出:20
println(sumF2(5,15)()) // 输出:20
}
计算并赋值操作符
比如 a += b
,编译器会试着生成代码 a = a+b
fun testComputeAndAssign(): Unit {
var a = 10
val b = 5
a += b
println(a) // 输出:15
a -= b
println(a) // 输出:10
a /= b
println(a) // 输出:2
a *= b
println(a) // 输出:10
a %= b
println(a) // 输出:0
}
相等与不等操作符
kotlin有两种类型的相等性:
- 引用相等,两个引用指向同一对象,符号:“===”和“!==”
引用相等,“===”和“!==”操作符不可重载。
- 结构相等,使用
equals()
函数判断,符号:“==”和“!=”
Elvis 操作符?:
kotlin中Elvis 操作符特定跟null进行比较。
使用Elvis 操作符可以有效避免空指针异常。
fun testElvis(): Unit {
val x = null
val y = x ?: 0 // 相当于: y = if (null!=x) x else 0
println(y)
val a = ""
val b = a ?:0 // a!==null, 返回a的值
println(b)
}
比较操作符
kotlin中比较表达式都转换为调用 compareTo()
函数,该函数返回 Int
值。
fun testCompare(): Unit {
val a = 10
val b = 5
println(a>b) // 输出:true
println(a.compareTo(b)>0) // 输出:true
println(a<b) // 输出:false
println(a.compareTo(b)<0) // 输出:false
println(a>=b) // 输出:true
println(a.compareTo(b)>=0) // 输出:true
println(a<=b) // 输出:false
println(a.compareTo(b)<=0) // 输出:false
println(a.compareTo(5)) // 输出:1
println(a.compareTo(10)) // 输出:0
println(a.compareTo(15)) // 输出:-1
}
infix 函数,自定义中缀操作符
重载操作符的函数需要用 operator
修饰符标记,
中缀操作符函数使用 infix
修饰符标记.
// 自定义 Int 的中缀操作符函数
infix fun Int.geek(x:Int) = (this + x)*2
fun testInfixF(): Unit {
val a = 5
val b = a geek 1
val c = a.geek(1)
println(a) // 5
println(b) // (5+1)*2 == 12
println(c) // (5+1)*2 == 12
}
data class Member(val name: String, val age: Int) // 声明数据类
infix fun Member.grow(years: Int) : Member { // 声明Member类的中缀操作符函数
return Member(name, age+years)
}
fun testInfixF2(): Unit {
val tyler = Member("Tyler", 20)
println(tyler.grow(7)) // 输出:Member(name=Tyler, age=27)
println(tyler grow 7) // 输出:Member(name=Tyler, age=27)
println(tyler) // 输出:Member(name=Tyler, age=20)
}