kotlin标准库中的Scope functions(作用域函数的使用)

kotlin标准库中的Scope functions(作用域函数的使用)

The Kotlin standard library contains several functions whose sole purpose is to execute a block of code within the context of an object. When you call such a function on an object with a lambda expression provided, it forms a temporary scope. In this scope, you can access the object without its name. Such functions are called scope functions. There are five of them: let, run, with, apply, and also.

Kotlin标准库包含几个函数,其唯一目的是在对象的上下文中执行代码块。当在提供了lambda表达式的对象上调用这样的函数时,它会形成一个临时作用域。在此范围内,您可以不使用对象的名称来访问对象。这种函数称为作用域函数。其中有五种:let、run、with、apply,还有also。

Basically, these functions do the same: execute a block of code on an object. What’s different is how this object becomes available inside the block and what is the result of the whole expression.

基本上,这些函数的作用是相同的:在对象上执行一段代码。不同的是,这个对象如何在块内可用,以及整个表达式的结果是什么。

The scope functions do not introduce any new technical capabilities, but they can make your code more concise and readable.

scope函数没有引入任何新的技术功能,但它们可以使代码更加简洁易读。

作用域函数的区别

作用域函数间的区别

let

fun testLet(){
    println("=======================使用let时:使代码简洁易懂==================================")
    Person("Alice", 20, "Amsterdam").let {
        println(it)
        it.moveTo("London")
        it.incrementAge()
        println(it)
    }


    println("=======================不使用let时=============================================")
    val mAlice:Person = Person("Alice", 20, "Amsterdam")
    println(mAlice)
    mAlice.moveTo("London")
    mAlice.incrementAge()
    println(mAlice)
}


fun main() {
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    val resultList = numbers.map { it.length }.filter { it > 3 }
    println(resultList)    
}

fun main() {
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.map { it.length }.filter { it > 3 }.let { 
        println(it)
        // and more function calls if needed
    } 
}

//如果代码块包含单个函数并将其作为参数,则可以使用方法引用(::)而不是lambda:
fun main() {
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.map { it.length }.filter { it > 3 }.let(::println)
}

//let通常用于仅使用非空值执行代码块。要对非空对象执行操作,请使用安全调用操作符?。并在其lambda中调用let。

fun main() {
    val str: String? = "Hello"   
    //processNonNullString(str)       // compilation error: str can be null
    val length = str?.let { 
        println("let() called on $it")        
        processNonNullString(it)      // OK: 'it' is not null inside '?.let { }'
        it.length
    }
}

//使用let的另一个例子是引入局部变量,以提高代码的可读性。要为上下文对象定义新变量,请将其名称作为lambda//参数提供,以便可以使用它来代替默认值。

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    val modifiedFirstItem = numbers.first().let { firstItem ->
        println("The first item of the list is '$firstItem'")
        if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
    }.uppercase()
    println("First item after modifications: '$modifiedFirstItem'")
}

run

fun testRun(){
    val mPerson=Person("Alice", 20, "Amsterdam")

    mPerson.run {
        println("age=$age,city=$city")
        println(this)
    }

}

fun main() {
    val hexNumberRegex = run {
        val digits = "0-9"
        val hexDigits = "A-Fa-f"
        val sign = "+-"

        Regex("[$sign]?[$digits$hexDigits]+")
    }

    for (match in hexNumberRegex.findAll("+123 -FFFF !%*& 88 XYZ")) {
        println(match.value)
    }
}

with

//在代码中,with可以理解为“with this object,do following”
fun main() {
    val numbers = mutableListOf("one", "two", "three")
    with(numbers) {
        val firstItem = first()
        val lastItem = last()        
        println("First item: $firstItem, last item: $lastItem")
    }
}

//with的另一个用例是引入一个辅助对象,其属性或函数将用于计算值。
fun main() {
    val numbers = mutableListOf("one", "two", "three")
    val firstAndLast = with(numbers) {
        "The first element is ${first()}," +
        " the last element is ${last()}"
    }
    println(firstAndLast)
}

also

fun main() {
    val numbers = mutableListOf("one", "two", "three")
    numbers
        .also { println("The list elements before adding new one: $it") }
        .add("four")
}

/**
 * apply和also的返回值是上下文对象本身
 * 它们可以作为辅助步骤包含在调用链中:可以在它们之后继续链接同一对象上的函数调用。
 */
fun testAlso(){
    val mPerson=Person("Alice", 20, "Amsterdam").also {
        writeToLog(it)
    }
    println(mPerson)
}


fun writeToLog(message: Person) {
    println("INFO: ${message.city}")
}

apply

/**
 * apply和also的返回值是上下文对象本身
 * 它们可以作为辅助步骤包含在调用链中:可以在它们之后继续链接同一对象上的函数调用。
 */
fun testApply(){
    val mPerson=Person("Alice", 20, "Amsterdam").apply {
        age=30
        city="漯河"
    }
    println(mPerson)
}

data class Person(var name: String, var age: Int = 0, var city: String = "")

fun main() {
    val adam = Person("Adam").apply {
        age = 32
        city = "London"        
    }
    println(adam)
}

//不使用apply时
private val mPageTransformer = ViewPager2.PageTransformer { page, position ->
        val absPos = Math.abs(position)
        page.rotation = if (rotateCheckBox.isChecked) position * 360 else 0f
        page.translationX= if (translateX) absPos * 350f else 0f
        page.translationY= if (translateY) absPos * 500f else 0f
        if (scaleCheckBox.isChecked) {
            val scale = if (absPos > 1) 0F else 1 - absPos
            page.scaleX = scale
            page.scaleY = scale
        } else {
            page.scaleX = 1f
            page.scaleY = 1f
        }
    }

//使用apply时
    private val mAnimator = ViewPager2.PageTransformer { page, position ->
        val absPos = Math.abs(position)
        page.apply {
            rotation = if (rotateCheckBox.isChecked) position * 360 else 0f
            translationY = if (translateY) absPos * 500f else 0f
            translationX = if (translateX) absPos * 350f else 0f
            if (scaleCheckBox.isChecked) {
                val scale = if (absPos > 1) 0F else 1 - absPos
                scaleX = scale
                scaleY = scale
            } else {
                scaleX = 1f
                scaleY = 1f
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值