1. kotlin的操作符可以重载,在方法前面加 operator 关键字,如下面的重载 + 运算符
data class Counter(var index: Int)
operator fun Counter.plus(increment: Int): Counter {
return Counter(index + increment)
}
fun main(args: Array<String>) {
val c = Counter(1)
val cplus = c + 10
println(cplus) //Counter(index=11)
}
2. Elvis 操作符 ?:
主要用来作null
安全性检查。用Elvis操作符不用检查null(避免了NullPointerException
),也不用重复变量。
String name = "Elvis Presley";
String displayName = name?:"Unknown"
3. infix函数自定义中缀操作符
fun main(args: Array<String>) {
val person = Person("Jack", 20)
println(person.grow(2))
println(person grow 2)
}
data class Person(val name: String, val age: Int)
infix fun Person.grow(years: Int): Person {
return Person(name, age + years)
}
输出如下:
Person(name=Jack, age=22)
Person(name=Jack, age=22)
Process finished with exit code 0
4. 扩展函数 和 扩展属性
扩展函数可以极大的简化编程,通常我们在顶层定义扩展,即直接在包里
扩展不是真正的修改他们所扩展的类。我们定义一个扩展,其实并没有在一个类中插入新函数,仅仅是通过该类型的变量,用点.
表达式去调用这个新函数。
由于扩展没有实际的将成员插入类中,因此对扩展的属性来说,它的行为只能由显式提供的 getters/setters 定义。
val <T> List<T>.lastIndex: Int
get() = size - 1
fun String.notEmpty(): Boolean {
return !this.isEmpty()
}
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // this对应该列表m
this[index1] = this[index2]
this[index2] = tmp
}
fun <T> MutableList<T>.mswap(index1: Int, index2: Int) {
val tmp = this[index1] // “this”对应该列表
this[index1] = this[index2]
this[index2] = tmp
}
-------------------------------
val a = "abc"
println(a.notEmpty())//true
val mList = mutableListOf<Int>(1, 2, 3, 4, 5)
println("Before Swap:")
println(mList)//[1, 2, 3, 4, 5]
mList.swap(0, mList.size - 1)
println("After Swap:")
println(mList)//[5, 2, 3, 4, 1]
val mmList = mutableListOf<String>("a12", "b34", "c56", "d78")
println("Before Swap:")
println(mmList)//[a12, b34, c56, d78]
mmList.mswap(1, 2)
println("After Swap:")
println(mmList)//[a12, c56, b34, d78]
上面的扩展函数和扩展属性,经过反编译后对应的Java代码如下:
public static final int getLastIndex(@NotNull List $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver.size() - 1;
}
public static final boolean notEmpty(@NotNull String $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
CharSequence var1 = (CharSequence)$receiver;
return var1.length() != 0;
}
public static final void swap(@NotNull List $receiver, int index1, int index2) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
int tmp = ((Number)$receiver.get(index1)).intValue();
$receiver.set(index1, $receiver.get(index2));
$receiver.set(index2, tmp);
}
public static final void mswap(@NotNull List $receiver, int index1, int index2) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
Object tmp = $receiver.get(index1);
$receiver.set(index1, $receiver.get(index2));
$receiver.set(index2, tmp);
}
5. 安全调用?.
和 非空断言调用 !!.
var na: String? = "abc"
na = null
println(na?.length)//输出null
如果要只对非空值执行某个操作,安全调用操作符可以与 let
(以调用者的值作为参数来执行指定的函数块,并返回其结果)一起使用:
val listWithNulls: List<String?> = listOf("A", "B",null)
listWithNulls.forEach{
it?.let{println(it)}
}
上面的代码经过反编译后,对应的Java代码如下:
List listWithNulls = CollectionsKt.listOf(new String[]{"A", "B", (String)null});
Iterable $receiver$iv = (Iterable)listWithNulls;
Iterator var3 = $receiver$iv.iterator();
while(var3.hasNext()) {
Object element$iv = var3.next();
String it = (String)element$iv;
if (it != null) {
System.out.println(it);
}
}