Kotlin操作符、运算符号用法大全
前言:)
Scala :想解决Java表达能力不足的问题
Groovy :想解决Java语法过于冗长的问题
Clojure:想解决Java没有函数式编程的问题
Kotlin :想解决Java
正文:)
1.与Java用法有差异的符号
- []
数组声明
java用[]和{}声明
int intArray2 [] = new int[]{20,21,22};
int intArray3 [] = {30,31,32};
kotlin用函数声明
var intArray2 = intArrayOf(20, 21, 22)
var intArray3 = intArrayOf(30, 31, 32)
数组与集合皆可用[]取值
val array = arrayOf(1, 2, 3)
for (i in array) {
println("the element at ${array[i] }")
}
val list = listOf(1, 2, 3)
for (i in list) {
println("the element at ${list[i] }")
println("the element at ${list.get(i) }")
}
等同于get函数,也可用于自定义操作符,更多请参见自定义操作符
public operator fun get(index: Int): E
- ==
Java中==比较的是引用地址
Kotlin中===与之相同
而==可直观比较结构相等,事实上也是用equals()函数
直观的等式
val john1 =Person(“John”)
val john2 =Person(“John”)
john1 == john2 // true(结构相等)
john1 === john2 // false(引用相等)
- ->
(1) 分隔 lambda 表达式的参数与主体(更多请参见函数)
{ x: Int, y: Int, z: Int -> x + y + z }
(2) 分隔在函数类型中的参数类型与返回类型声明
fun printSum(sum: (Int) -> String) {sum(1)}
(3) 分隔 when 表达式分支的条件与代码体
when (a) {
11, 12 -> print("x is in 11,12")
in 1..10 -> print("x is in the range")
is Int -> print("x is Int")
!in 10..20 -> print("x is outside the range")
a.println() -> print("x println")
else -> {
print("else1")
print("else2")
}
}
2.Kotlin空安全
关于空安全的设计讨论
Kotlin 区别 nullable 类型并强制程序员显式地添加 null 检查。
NullPointerException (NPR) 问题广泛存在于默认引用语义的许多程序设计语言中,不只是 Java,还有 C#,Python,
也是广大程序员头痛不已的问题之一
解决 NPR 引起的 bug 的确是程序员的责任,但作为工具的程序设计语言在语言层面帮助程序员避开 bug
并不是罪过。
在程序分析的基础上强制一些啰嗦但安全的编码规则,分担一部分程序员之后书写和维护测试用例的压力,
也是很有价值的事。
- ?
Kotlin类型系统分为可空类型
和不可空类型
定义变量时,可在类型后面加一个问号?,表示该变量是Nullable,可以接收null,类型默认不可接收null。
val canBeNull: String? = null
val i: Int? = null
val breakHere : String = canBeNull // Type mismatch
val assigned: String = if (canBeNull == null) "test" else canBeNull // Pass
泛型声明
val list: ArrayList = ArrayList()
list.add(1)
list.add(null)
list.add(1)
Kotlin中无论是
成员属性
还是局部变量
都需要初始化,否则编译期给出错误提示
var vara :String //error :property must be initialized //属性必须初始化
fun test0() {
var vara: String
vara.toString()//error :variable must be initialized //变量必须初始化
}
如果你能确定这个成员变量在使用过程中前会被赋值的话可以用关键字lateinit来修饰
lateinit var bar: String
- !!
修饰后转成 不可接收null类型
fun test012(){
var a: String? = "abc"
var b: String = a!!
}
Kotlin 对 nullable 的检查更多地是通过控制流分析进行,辅以类型系统。
- ?.
安全调用
val b: String? = null
println(b?.length)
判空
// Java
if (message != null) {
System.out.println(message)
}
// Kotlin
message?.let { println(it) }
结合作用域函数(更多请参见作用域函数)
val nullVal: Any? = null
nullVal?.let {
println("[nullVal] not null code block")
}
- ?:
如果 ?: 左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式
val l: Int = if (b != null) b.length else -1
val l = b?.length ?: -1
- !!.
不安全调用
如果你想要一个 NPE,你可以得到它,但是你必须显式要求它,否则它不会不期而至
val l = b!!.length
try {
b!!.length
} catch (e: KotlinNullPointerException) {
}
可空类型的集合 过滤非空元素
val nullableList: List = listOf(1, 2, null, 4)
val intList: List = nullableList.filterNotNull()
3.其他新增
- """
三个双引号, 字符串字面值
val text = """
第一行
第二行
第三行
""".trimMargin()//函数去除前导空格
- $
优先使用字符串模板或原始字符串而不是字符串连接。 花括号括起来的任意表达式
val s = "abc"
println("$s 的长度为 ${s.length}")
- _
字面常量 ,数字字面值中的下划线,同Java用法
val oneMillion = 1_000_000
解构中使用,缺省
//list forEach
val array = listOf(1, 2, 3)
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
//map forEach
val map1 = mapOf("1" to 1, "2" to 2)
map1.forEach { key, value -> println("$key&$value!") }
//缺省
map1.forEach { _, value -> println("$value!") }
数组解构
val (param,car) = "param=car=c".split("=")
val (c, car) = "param=car=c".split("=").reversed()
- ::
函数的引用 类似对象的引用
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))//引用自定义函数
listOf(1, 2, 3).forEach(::println) //引用标准库函数
属性的引用
val x = 1
println(::x)
类名
Data::class.java
可以通过将方法引用存储在具有显式指定类型的变量中
val predicate: (Int) -> Boolean = ::isOdd // 引用到 isOdd(x: String)
- ..
范围
for (i in 1..10) { }
- +
"" + ""
- -=
val aList = mutableListOf(1, 2, 3)
val bList = mutableListOf(1, 2)
aList-=bList //removeAll
操作符源码
//..
public operator fun rangeTo(other: Int): IntRange
//+
public operator fun plus(other: Any?): String
//-=
@kotlin.internal.InlineOnly
public inline operator fun MutableCollection.minusAssign(elements: Iterable) {
this.removeAll(elements)
}
- @
循环标记
loo@ for (i in 1..10) {
for (a in 1..10) {
break@loo//自定义标记名
}
}
val list = listOf(1, 2, 3, 4)
fun a() {
list.forEach {
println("it=$it")
if (it == 3) return@a //声明一个函数
}
}
list.forEach {
println("it=$it")
if (it == 3) return@forEach // forEach做为标记
}
外部类标记
class Outter {
inner class Inner {
fun getData(): Outter {
return this@Outter
}
}
}
注解
object Demo {
@JvmStatic
fun test() {
}
}
fun funVararg(vararg strings: String) { /*……*/
}
val funVararg1 = funVararg("a", "b", "c")
val funVararg2 = funVararg(strings = *arrayOf("a", "b", "c"))
BONUS TIME
?:
Elvis 操作符 Elvis即猫王的名字
- Elvis GIF