kotlin let表达示_了解Kotlin示波器功能

kotlin let表达示

Plenty of Android Developers have by now moved to Kotlin from Java and are benefiting from the awesome power that the language offers. Kotlin has a bunch of features that make our code more concise and less error-prone. One such feature is scope functions. If you have been developing in Kotlin, chances are you have used them already. However, have you used all of them and how can you leverage their power effectively?

到目前为止,大量的Android开发人员已从Java转移到Kotlin,并从该语言提供的强大功能中受益。 Kotlin具有许多功能,可以使我们的代码更简洁,更不易出错。 示波器功能就是这样的功能之一。 如果您在Kotlin进行开发,那么您可能已经使用过它们。 但是,您是否使用了所有这些功能,又如何有效利用它们的功能?

What are Kotlin scope functions?

什么是Kotlin示波器功能?

According to the official documentation, scope functions

根据官方文档,作用域功能

execute a block of code within the context of an object

在对象的上下文中执行代码块

The resulting block of code is run within a lambda, which in turn provides a temporary scope that allows you to access your receiver (the object) without using its name. Depending on the scope function you use, the object can be accessed using it or this. There are five scope functions in Kotlin namely let, run, with, also and apply. To get a good grasp of what each does, it is better to see examples.

生成的代码块在lambda内运行,这又提供了一个临时范围,使您无需使用其名称即可访问接收器(对象)。 根据您使用范围功能,对象可以使用访问。 Kotlin中有五个作用域函数,即let run with alsoapply。 为了更好地理解每个功能,最好查看示例。

Want to read this story later? Save it in Journal.

想稍后再读这个故事吗? 将其保存在 Journal中

For the sake of the demonstration, we shall be using the following Animal class.

为了演示,我们将使用以下动物类。

class Animal() {
var name = "Panda"
var origin = "Wherever pandas come from"
var colour = "Black and White"
}

let

The let function allows you to perform a certain operation on an object and return a value if you want. By default, the last statement in a let block is a return statement if it is not an assignment. If you do not return a value in the let block, it is the same as calling a function that contains no return value. See the following code examples.

let函数允许您对对象执行特定操作,并根据需要返回值。 默认情况下,let块中的最后一条语句(如果不是赋值的话)是return语句。 如果未在let块中返回任何值,则与调用不包含任何返回值的函数相同。 请参见以下代码示例。

private fun letExample() {
val animal = Animal().let {
//The it is the object, which is Animal in this case
"The animal is from: ${it.origin}"
}
print(animal)
}//Will print the following
The animal is from Wherever pandas come from

If you take a look at the code within the let block, the last statement is not an assignment so it is returned. If we changed it a bit to the following

如果您查看let块中的代码,则最后一条语句不是赋值,因此将其返回。 如果我们将其更改为以下内容

private fun letExample() {
val animal = Animal().let {
//The it is the object, which is Animal in this case
it.origin = "Nigeria"
}
print(animal)
}//Will print the following
Kotlin.Unit

The last statement in the block is an assignment. That is, we are assigning the origin to a new value and are not returning anything.

块中的最后一条语句是赋值。 也就是说,我们正在将原点分配给新值,并且不返回任何内容。

In the case of let, the object context is obtained using it. If you are familiar with lambdas, you can rename the it to whatever you like for readability, especially if you are dealing with nested blocks. Thus, looking at the previous example, we can have:

let的情况下使用对象上下文获得对象上下文。 如果您熟悉lambda,则可以将其重命名为任何您喜欢的可读性,尤其是在处理嵌套块时。 因此,看看前面的示例,我们可以得到:

private fun letExample() {
val animal = Animal().let {animal ->
//it has been renamed to animal for readability
"The animal is from: ${animal.origin}"
}
print(animal)
}//Will print the following
The animal is from Wherever pandas come from

The let function is also particularly useful in ensuring null safety. For example, if we make the attribute origin as nullable and we wanted to access it, then we can simply do the following thus saving us from lengthy null checks

let函数在确保无效安全性方面也特别有用。 例如,如果我们将属性origin设置为可为空,并且想要访问它,那么我们只需执行以下操作即可,从而避免了冗长的null检查

private fun letExample() {
val animal = Animal().origin?.let {origin ->
//The it is has now become the attribute origin
"The animal is from: $origin"
}
print(animal)
}//Will print the following
The animal is from Wherever pandas come from

Finally, let is extremely useful if you want to perform an operation on a result you get from chaining calls. Consider the following where other list contains objects of type Person, which has an age attribute. The following code filters the Person objects and gets a list of only those of age 18 or higher.

最后,如果要对链接调用得到的结果执行操作,let是非常有用的。 请考虑以下情况,其中其他列表包含具有“年龄”属性的“人”类型的对象。 以下代码过滤Person对象,并仅获取18岁以上的对象的列表。

val list = otherList.filter{it.age > 18}
print(list)

With let, you can simplify this to the following

有了let,您可以将其简化为以下内容

//The it in the let block is the result of the chaining call
otherList.filter{it.age > 18}.let{print(it)}

apply

应用

Unlike let, apply uses this to refer to the context of the object.

let不同,apply使用来引用对象的上下文。

private fun applyExample() {
val animal = Animal().apply {
//this is the object, which is Animal in this case
name = "Tiger" //Similar to this.name
origin = "India" //Similar to this.origin
}
print("The new animal is a ${animal.name} and is from ${animal.origin}")
}//Output
The new animal is a Tiger and is from India

Note that we do not have to specifically use this.name or this.origin. You can do it if you want to or, you can rename this to another name if you have multiple nested lambdas.

注意,我们不必专门使用this.name或this.origin 。 你可以做,如果你想,或者,如果您有多个嵌套的lambda表达式可以重命名为另一个名称。

run

Run is quite similar to let in the sense that you can return a value of a different type from the receiver. However, the contextual object is this instead of it. Run is especially useful if you want to initialize an object and then compute a return value like the following

从某种意义上说,您可以返回与接收方不同类型的值,从某种意义上说, 运行让我们非常相似。 但是,上下文对象是而不是它。 如果要初始化一个对象然后计算如下的返回值,则运行特别有用。

private fun runExample() {
print(
Animal().run {
//this is the object, which is Animal in this case
name = "Great Dane"
origin = "Denmark"
"The animal is called $name and is from $origin"
}
)
}//Will print
The animal is called Great Dane and is from Denmark

with

With and run are similar down to their use of the this keyword. Using the previous example above, we can rewrite it to get the following

Withrun类似于使用this关键字。 使用上面的上一个示例,我们可以将其重写以获取以下内容

private fun withExample() {
val animal = with(Animal()) {
"The name of the animal is $name and the origin is $origin"
}
println(animal)
}//output
The name of the animal is Panda and the origin is Wherever pandas come from

also

The also scope function has similarities to let in that the context of the receiver is it while providing null checks as well. Additionally, the return value is the object. This means the following code will not actually print the value in the also block

的范围具有功能相似性,所述接收器的上下文是同时提供null检查以及 。 此外,返回值是对象。 这意味着以下代码实际上不会在Also块中打印该值

private fun alsoExample() {
val animal = Animal().also {animal ->
"The name of the animal is ${animal.name}"
}
println(animal)
}//Will not print the string but the address of the object

To print the line, then you do the following

要打印行,请执行以下操作

private fun alsoExample() {
Animal().also { animal ->
println("The name of the animal is ${animal.name}")
}}//output
The name of the animal is Panda

If you wish to change the return value from the receiver type, you can chain those calls like below

如果您想更改接收器类型的返回值,则可以像下面这样链接这些调用

private fun alsoExample() {
val animal = Animal().also { animal ->
println("The name of the animal is ${animal.name}")
animal.name = "Tiger new name"
}.run {
"The new name of the animal is now $name"
}
println(animal)
}//output
The name of the animal is Panda
The new name of the animal is now Tiger new name

By chaining the call with run, the type of animal now changes to a string and thus can be printed.

通过将调用与run链接起来动物的类型现在变为字符串,因此可以打印出来。

Final thoughts

最后的想法

Admittedly, they are quite a lot to take in at first. As such, you may be confused as to how you choose the right function to use. Most of the time, this will be up to you. However, if you wish to get a more in-depth understanding of the same, then you can look at the official documentation and this chart.

诚然,一开始他们要吸收很多东西。 因此,您可能对如何选择要使用的正确功能感到困惑。 在大多数情况下,这取决于您。 但是,如果您希望对此有更深入的了解,则可以查看官方文档此图表

Happy coding and thanks to Claudio Agostini for pointing out some mistakes that have now been fixed.

祝您编程愉快,并感谢Claudio Agostini指出了一些已修复的错误。

Enjoy!

请享用!

PS: Let us connect on GitHub, Twitter, and LinkedIn.

PS:让我们在GitHubTwitterLinkedIn 上进行连接。

📝 Save this story in Journal.

story将这个故事保存在Journal中

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

every‍💻每个星期天早晨,您都可以在收件箱中等待本周最值得关注的Tech故事。 阅读Tech Newsletter中的“值得注意”

翻译自: https://blog.usejournal.com/understanding-kotlin-scope-functions-7328812acf19

kotlin let表达示

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值