kotlin作用域函数let,run,with,apply,also

237 阅读2分钟

0.前言

刚刚接触这几个作用域函数真的是傻傻分不清楚,完全搞不懂。经过一段时间的使用和学习,发现。为什么官方把它们叫做作用域函数呢?因为它们最大的作用是规范代码,把对象的一些列操作限定在一个代码块中(作用域)。各个对象层次分明,结构清晰。

不同的作用域函数,区别在于以用调用对象的方式和返回值。

1.先看一段

如下代码通过代码初始化textView属性,margin,shape圆角,可以说是用kotlin写的java代码。

即便在代码中添加了注释和空行分隔,可读性也没有那么好。

//代码创建 drawable 添加背景色 圆角
val drawable = GradientDrawable()
drawable.color= ContextCompat.getColorStateList(applicationContext, R.color.purple_700)
drawable.cornerRadius= 16f

//获取 LayoutParams 设置margin
val margin =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f,resources.displayMetrics)
        .toInt()
val layoutParams = mBinding.tvButton.layoutParamsas ViewGroup.MarginLayoutParams
//为了代码效果 没有调用 setMargins()
layoutParams.marginStart= margin
layoutParams.marginEnd= margin
layoutParams.topMargin = margin
layoutParams.bottomMargin = margin

//初始化 textView属性
mBinding.tvButton.textSize= 18f
mBinding.tvButton.setTextColor(ContextCompat.getColor(applicationContext, R.color.white))
mBinding.tvButton.text= "按钮"
mBinding.tvButton.gravity= Gravity.CENTER
mBinding.tvButton.background= drawable
mBinding.tvButton.layoutParams= layoutParams

2.作用域函数操作

使用作用域函数后,不同对象的代码被限制在各自的代码块中。

代码中为了给layoutParams 设置margin初始化了一个局部变量 margin。 在传统操作中margin变量任意一个变量都可以访问到。

但实际上只有layoutParams 才用到。 而使用kotlin作用域函数后,margin变量就只能由layoutParams访问,体现出了作用域的概念。

				//代码创建 drawable 添加背景色 圆角
        val drawable = GradientDrawable().apply {
            color = ContextCompat.getColorStateList(applicationContext, R.color.purple_700)
            cornerRadius = 16f
        }
        //设置margin
        val layoutParams = mBinding.tvButton.layoutParams as ViewGroup.MarginLayoutParams
        layoutParams.run {
            val margin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics).toInt()
            marginStart = margin
            marginEnd = margin
            topMargin = margin
            bottomMargin = margin
        }
        //初始化 textView属性
        mBinding.tvButton.let {
            it.textSize = 18f
            it.setTextColor(ContextCompat.getColor(applicationContext, R.color.white))
            it.text = "按钮"
            it.gravity = Gravity.CENTER
            it.background = drawable
            it.layoutParams = layoutParams
        }

3.作用域函数的区别

  1. 从返回值看
    1. also,apply属于同一类,返回调用对象
    2. let,run,with属于一类,最后一行不是return语句或一个变量时,不返回。图2说明如何返回值
  2. 从上下文对象引用方式看
    1. also,let属于一类,通过it引用对象
    2. apply,run,with属于一类,可直接调用属性

Untitled.png

Untitled 1.png