Kotlin中的crossinline

这一篇看下crossinline,同样他也要在inline函数中才能使用
先来看下这样2种情况
情况1:

fun mainInline2(func1: () -> Unit) {
     
        func1()
}


override fun onCreate(savedInstanceState: Bundle?) {
     

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mainInline2 {
      
        	print("return")
            return  //编译会报错,不允许使用return
        }
    }

这是一个常规的函数如果func1的函数体包含return是不允许的,但是如果我们按照他可以允许的逻辑来看,这个return应该返回的是func1函数。

情况2:

inline fun mainInline2(func1: () -> Unit) {
     
        func1()
}

其他的不变,我们将mainInline2声明为inline函数,这时候是可以在func1函数内部使用return的,但是由于这是内联函数,调用处就是这样

protected void onCreate(@Nullable Bundle savedInstanceState) {
     
      super.onCreate(savedInstanceState);
      this.setContentView(1300009);
      int $i$f$mainInline2 = false;
      int var4 = false;
      String var5 = "return";
      boolean var6 = false;
      System.out.print(var5);
      return //为了形象描述 自己添加的,原字节码没有这行
   }

从前面的文章知道,内联函数会将函数体直接复制到调用处,所以这个return返回的就是外部的onCreate函数

如果2种情况都是允许的话,会出现一个情况,我们调用一个函数,如果内部有return,返回的到底是哪个函数呢,是与return临近的函数还是最外部的,这个得看是内联函数还是普通函数。
(但是我们也不能每次调用一个函数都去看一下他是普通函数还是内联函数)

所以Kotlin的规定就是:
只有内联函数的函数类型参数内部可以有return 也就是上面的情况2中的func1能有return
(但是都可以使用return@xxx,即带标签的return语句,等于明确指定了返回地方)

接下来再说到crossinline,我们再将上面的函数改一下

inline fun mainInline2(func1: () -> Unit) {
     
        runOnUiThread {
     
            func1()  //编译器报错
        }
    }

我们在内联函数中添加一个runOnUiThread,然后在他内部调用func1函数,编译器报错,会提醒func1可能包含这非当前返回的return,这样又回到了之前的歧义问题,如果func1包含了return,那么这个return返回的是runOnUiThread还是更外部的调用函数就有歧义,如果想这样去间接调用,我们就需要加上crossinline

inline fun mainInline2(crossinline func1: () -> Unit) {
     
        runOnUiThread {
     
            func1()
        }
    }

这样就不再报错,这是为啥呢,如果我们在调用mainInline2的时候就会发现

override fun onCreate(savedInstanceState: Bundle?) {
     

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mainInline2 {
     
            print("return")
            return  //报错
        }
    }

调用的时候,我们在函数体内部加入return发现编译器报错,不允许我们在函数体内加入return,所以也就不存在歧义,因为crossinline直接禁止标记的函数内部包含return。

小结:如果想允许间接调用函数类型参数,添加crossinline

你可能感兴趣的:(kotlin,Kotlin,crossinline)