kotlin中为什么?:运算符会失效?

115 阅读1分钟

在如下代码中,typeInfo必然不为null,而getName()可能为null。当为null时,如下代码分别输出的是什么内容?

val res0 = typeInfo?.getName(manager!!)?.toString()
    ?: defalutValue

 val res1 = typeInfo?.getName(manager!!).toString()
    ?: defalutValue   
    

分别输出的内容为defaultValue和字符串“null”。输出null字符串的原因为当getName返回的为null时,会将其转成字符串“null”(下面第9行),因此后面的defalutValue压根不执行。

通过将以上的kotlin代码转出java可以看出,第二种情况会将null对象转成String字符串。


String var25;
label60: {
   if (appInfo != null) {
      Intrinsics.checkNotNull(manager);
      CharSequence var24 = typeInfo.getName(manager);
      if (var24 != null) {
         var25 = var24.toString();
         if (var25 != null) {
            break label60;
         }
      }
   }

   var25 = packageName;
}

String appName = var25;

第二种情况为使用

CharSequence var24;
if (appInfo != null) {
   Intrinsics.checkNotNull(manager);
   var24 = typeInfo.getName(manager);
} else {
   var24 = null;
}

String var26 = String.valueOf(var24);
if (var26 == null) {
   var26 = packageName;
}

String appName = var26;

注意 当使用?.调用时,需要从头到尾的都使用?.的方式进行调用。避免?:后面的内容不会被执行。

除了以上方式外还有如下几种方式,在未满足条件时执行代码块。

  1. val a = b?.let{ b} ?:{}()
  2. val a = b?.let{ b} ?:{}.invoke()
  3. val a = b?.let{ b} ?:run{}

以上方式需要注意的是默认返回的是Unit,lambda的最后一行为返回值。