Kotlin inline 关键字


前言

最近又到了面试的季节,今天在面试中被问到了kotlin inline 关键字 ,感觉回答的不是很好,今天研究一下它


一、inline 是什么?

inline 是kotlin 中的关键字,中文叫做内嵌 ,可以用来优化我们的代码,怎么优化呢? 通过减少方法嵌套的方式,我们接下来来验证一些这个过程。

二、未使用

代码如下

下边面是登录的一个需求

object LoginUtils {

    /**
     * 请求登录
     * @param block true 表示登录成功
     */
    fun requestLogin(block: (Boolean) -> Unit) {
    	.....
        block(true)
    }

}

---

fun main() {
    LoginUtils.requestLogin {
        if (it) {
            logD("登录成功")
        }
    }
}

相信大家经常会遇到这种情况,如果成功成功做一些授权处理,那么我们将他转成java 代码看一下吧

 public final void requestLogin(@NotNull Function1 block) {
      Intrinsics.checkParameterIsNotNull(block, "block");
      block.invoke(true);
   }

ok,现在看起来一切正常,如我们所料,kotlin中的lambad 也就是我们常用的接口,使用接口回调来返回到我们的调用方。

我们会把用户信息在本地做一些缓存,避免耗费流量等一系列的原因,我们会先去查询下本地数据库是否存在

object LoginUtils {

    /**
     * 请求登录
     * @param block true 表示登录成功
     */
    fun requestLogin(block: (Boolean) -> Unit) {
        //读取本地用户信息,是否存在
        DbUtils.getUserInfo {
            if (it.token.isNotEmpty()) {
                block(true)
            } else {
                block(false)
            }
        }
    }
}
--- java 代码如下
public final void requestLogin(@NotNull final Function1 block) {
      Intrinsics.checkParameterIsNotNull(block, "block");
      DbUtils.INSTANCE.getUserInfo((Function1)(new Function1() {
         // $FF: synthetic method
         // $FF: bridge method
         public Object invoke(Object var1) {
            this.invoke((User)var1);
            return Unit.INSTANCE;
         }

         public final void invoke(@NotNull User it) {
            Intrinsics.checkParameterIsNotNull(it, "it");
            CharSequence var2 = (CharSequence)it.getToken();
            boolean var3 = false;
            if (var2.length() > 0) {
               block.invoke(true);
            } else {
               block.invoke(false);
            }

         }
      }));

我们这里可以看到 存在了两个 Function1 回调 分别在requestLogin和getUserInfo 参数里,像这种类似的场景在我们项目中其实是非常常见的,刚刚我们在上边我们说过inline 可以减少我们方法的嵌套,那么我们下边使用inline 关键字来优化下这块代码。

2.使用后

代码如下

接下来我们将带有lambad 的方法LoginUtil#requestLogin 和 DbUtils# getUserInfo通过inline 关键字添加修饰


--LoginUtil
 
public final void requestLogin(@NotNull Function1 block) {
      ....
      DbUtils this_$iv = DbUtils.INSTANCE;
      .....
      String var10004 = UUID.randomUUID().toString();
      .....
      User it = new User("zzzqqqyyy@163.com", "123f42t523", var10004);
      int var6 = false;
      CharSequence var7 = (CharSequence)it.getToken();
      boolean var8 = false;
      if (var7.length() > 0) {
         block.invoke(true);
      } else {
         block.invoke(false);
      }

   }

这是我们请求登录的方法但是我们对比之前的方法会发现,与之前的代码有些不同,我们这里发现我们上边的Function1 也就是接口回调存在两个,但是现在只有一个了,就好像他把我们 DbUtils#getUserInfo搬到了 LoginUtils#requestLogin 方法内,从而减少了一层嵌套,但是我们这里还有一层嵌套,我们接着往下看。

LoginUtil#requestLogin 方法实在 mani方法里,我们看一下

 public static final void main() {
      LoginUtils this_$iv = LoginUtils.INSTANCE;
      ...
      DbUtils this_$iv$iv = DbUtils.INSTANCE;
      ....
      String var10004 = UUID.randomUUID().toString();
      ....
      User it$iv = new User("zzzqqqyyy@163.com", "123f42t523", var10004);
      int var5 = false;
      CharSequence var6 = (CharSequence)it$iv.getToken();
      boolean var7 = false;
      boolean it;
      boolean var9;
      if (var6.length() > 0) {
         it = true;
         var9 = false;
         if (it) {
            logD("登录成功");
         }
      } else {
         ....
      }
   }

main 里面的方法同时存在了 LoginUtil#requestLogin 和 DbUtil$getUserInfo方法,我们会发现两个Function1接口回调,都没了, 我们方法的调用顺序是main -> requestLogin -> getUserInfo 后两个都被inline 关键字 ,所以到这里可以真正的理解内嵌的意义所在了


总结

通过上边的验证我们可以确认 所有被linline 关键字修饰的方法,该方法体的内容都会被替换到调用者的方法体内,如果有lanmbad 会优化掉一个接口回调,如果我们正常的参数替换过来是没有太大意义的,所以 inline 关键字适合在存在lambad 参数的方法上进行修饰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值