How to choose these scope functions
In Kotlin development, some scope functions such as let
, apply
, also
, etc. are often used. For details about what a scope function is, you can read the official website address of the scope function . I won’t go into details here. If you don’t understand, you can read the official documentation.run
In our actual use, you may have such doubts about which scope function to use. It seems that in some cases, each one can be used. In some cases, only specific functions can be used?
In fact, to understand this, you need to understand the characteristics of these functions. To distinguish the differences between these functions, we can distinguish them from three dimensions: whether it is an extension function, the return value difference, and what the parameters are. You can take a look at the table below:
function | Corresponding citation method | return value | Is it an extension function? |
---|---|---|---|
let |
it |
Lambda result | Yes |
run |
this |
Lambda result | Yes |
run |
- | Lambda result | No: called without the context object |
with |
this |
Lambda result | No: takes the context object as an argument. |
apply |
this |
Context object | Yes |
also |
it |
Context object | Yes |
The above table is the table on the official website, listing the differences of each function in various dimensions. But it still seems not intuitive enough, so here I make a "decision diagram" to choose which function to use . You can take a look at it.
So next time you don’t know which one to use, you can just choose according to this picture~~~
Usage issues
Now Kotlin is basically the main language for development, and scope functions are also widely used in development. But when using scope functions, we encountered some typical problems. These problems will also be seen when reviewing other people's codes, which means that everyone may have encountered these problems. Here we select the two most common ones for explanation.
1. Too many nested uses
It is often seen that there are many nested use of scope functions in the code. For example:
fun getUserFriendsInfo() {
userId?.let {
val userInfo = getUserInfo(it)
userInfo?.apply {
val friends = getFriendsByUserInfo(userInfo)
friends?.apply {
......
}
}
}
}
As you can see from the above code, if you use too many nested scope functions, it will form. 类似“回调地狱”的代码形式
In addition, some are also used in the code lambdas
, and the situation is even more serious, making the code extremely ugly. In our projects, we often see similar code. So what can be done to improve it?
I think there are several methods as follows:
- One is to extract the code and put it into different functions to reduce nesting.
- In many cases, it is necessary to make a short judgment in advance, or define it
Contract
, and then the variable will be in a non-empty state, so that there is no need to judge everywhere and reduce nesting.
2. Parameter this/it and reference confusion
Some scope functions are passed with parameters, some are this, some are it, and if they are used in nests, there will be problems with code readability and even errors. Here are a few examples:
First example:
fun getUserFriendsInfo() {
userId?.let {
val userInfo = getUserInfo(it)
userInfo?.let {
val friends = getFriendsByUserInfo(it)
friends?.let {
println(it)
......
}
}
}
}
In the above code, you can see that there are three it. Which one is which is sometimes not necessarily easy to distinguish. Similarly, scope functions whose other parameters are it also have this problem.
Second example:
class Style() {
var width = 0.0
var height = 0.0
var name = ""
}
class Widget(val name: String, val width: Double) {
val style: Style
init {
val height = width * 1.5
style = Style().apply {
width = width
name = name
}
}
}
In the above code, apply
inside the method. Widget
and width、name
have Style
the same name, sometimes it is impossible to distinguish clearly, or even an error is reported. How to deal with these situations?
- Don’t use the default naming, such as it, try to rename it to something meaningful.
- Don’t use heavily nested scope functions
- For scope functions like this where there is no way to rename parameters, you can use labels
apply
when referencing variables , such as the example above.label
apply
class Widget(val name: String, val width: Double) {
val style: Style
init {
val height = width * 1.5
style = Style().apply {
// 使用标签
this.width = this@Widget.width
this.height = height
this.name = this@Widget.name
}
}
}
at last
If you want to become an architect or want to break through the 20-30K salary range, then don't be limited to coding and business, you must be able to select and expand, and improve your programming thinking. In addition, good career planning is also very important, and learning habits are important, but the most important thing is to be able to persevere. Any plan that cannot be implemented consistently is empty talk.
If you have no direction, here is a set of "Advanced Notes on the Eight Major Modules of Android" written by a senior architect at Alibaba to help you systematically organize messy, scattered, and fragmented knowledge, so that you can systematically and efficiently Master various knowledge points of Android development.
Compared with the fragmented content we usually read, the knowledge points in this note are more systematic, easier to understand and remember, and are strictly arranged according to the knowledge system.
Welcome everyone to support with one click and three links. If you need the information in the article, just scan the CSDN official certification WeChat card at the end of the article to get it for free↓↓↓ (There is also a small bonus of ChatGPT robot at the end of the article, don’t miss it)