Kotlin笔记2-操作符和扩展方法

 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);
         }
      }

猜你喜欢

转载自blog.csdn.net/unicorn97/article/details/81292920
今日推荐