Kotlin – 作用域函数
Kotlin 标准库中有几个函数可以帮助在对象上下文中执行代码块。使用 lambda 表达式在对象上调用这些函数会创建一个临时作用域。这些函数称为作用域函数。我们可以在没有名称的情况下访问这些函数的对象。听起来很混乱!我们来看一个例子,
示例:不使用作用域函数
Kotlin
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
// without using scope function
// creating instance of Company Class
val gfg = Company()
// initializing members of the class
gfg.name = "GeeksforGeeks"
gfg.objective = "A computer science portal for Geeks"
gfg.founder = "Sandeep Jain"
println(gfg.name)
}
Kotlin
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
// using scope function
val gfg = Company().apply {
// don't need to use object
// name to refer members
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
founder = "Sandeep Jain"
}
println(gfg.name)
}
Kotlin
fun main() {
// nullable variable a
// with value as null
var a: Int? = null
// using let function
a?.let {
// statement(s) will
// not execute as a is null
print(it)
}
// re-initializing value of a to 2
a = 2
a?.let {
// statement(s) will execute
// as a is not null
print(a)
}
}
Kotlin
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
Company().apply {
// same as founder = “Sandeep Jain”
this.founder = "Sandeep Jain"
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
}
}
Kotlin
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
val gfg = Company().apply {
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
founder = "Sandeep Jain"
}
// with function
with(gfg) {
// similar to println( "${this.name}" )
println(" $name ")
}
}
Kotlin
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main(args: Array) {
println("Company Name : ")
var company: Company? = null
// body only executes if
// company is non-null
company?.run {
print(name)
}
print("Company Name : ")
// re-initialize company
company = Company().apply {
name = "GeeksforGeeks"
founder = "Sandeep Jain"
objective = "A computer science portal for Geeks"
}
// body executes as
// 'company' is non-null
company?.run {
print(name)
}
}
Kotlin
fun main() {
// initialized
val list = mutableListOf(1, 2, 3)
// later if we want to perform
// multiple operations on this list
list.also {
it.add(4)
it.remove(2)
// more operations if needed
}
println(list)
}
Kotlin
Company().apply {
// same as : name = "GeeksforGeeks"
this.name = "GeeksforGeeks"
this.founder = "Sandeep Jain"
this.objective = "A computer science portal for Geeks"
}
Kotlin
Company().let {
it.name = "GeeksforGeeks"
it.founder = "Sandeep Jain"
it.objective = "A computer science portal for Geeks"
}
Kotlin
class Company {
var name: String = "GeeksforGeeks"
var founder: String = "Sandeep Jain"
var objective: String = "A computer science portal for Geeks"
}
fun main() {
val founderName: String = with(Company()) {
// 'founder' is returned by 'with' function
founder
}
println("GfG's Founder : $founderName")
}
Kotlin
class Company {
var name: String = "GeeksforGeeks"
var founder: String = "Sandeep Jain"
var objective: String = "A computer science portal for Geeks"
}
fun main() {
val gfg = Company().apply {
// any statement(s)
}
// gfg is an object of class Company as
// return of apply() is context object
print("GfG's Founder : ${gfg.founder}");
}
输出:
GeeksforGeeks
示例:使用范围函数
科特林
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
// using scope function
val gfg = Company().apply {
// don't need to use object
// name to refer members
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
founder = "Sandeep Jain"
}
println(gfg.name)
}
输出:
GeeksforGeeks
解释
你一定注意到了,当我们不使用作用域函数的时候,每次都需要写对象名来引用类的成员。使用作用域函数时,我们可以直接引用成员,而无需对象名称。这是使用 scope函数的方法之一。我们将在本文中详细了解它们。
作用域函数
每个作用域函数都有明确定义的用例,尽管它们都有几乎相同的结果。现在让我们看看每个作用域函数及其用例:
作用域函数的应用
作用域函数使代码更加清晰、可读和简洁,这是 Kotlin 语言的主要特点。
作用域函数的类型
作用域函数有五种类型:
- 让
- 跑
- 和
- 申请
- 还
这些功能中的每一个在本质上都非常相似,只有细微的差别。决定使用哪个函数以及何时使用常常令人困惑。因此,我们需要知道这些功能及其用例之间有什么区别。
这些功能的区别:
这些功能主要有两个区别:
- 引用上下文对象的方式(即使用“this”或“it”关键字)
- 返回值(即返回“上下文对象”或“lambda 结果”)
Note: Context object refers to the object on which we are using the scope functions. As in our previous example – ‘gfg’ is our context object
范围函数表: Function Object Reference Return Value let it Lambda result run this Lambda result with this Lambda result apply this Context object also it Context object
1.让函数
Context object : it
Return value : lambda result
用例:
let函数通常用于提供空安全调用。将安全调用运算符(?.)与 'let' 一起使用以确保空值安全。它仅使用非空值执行块。
例子:
科特林
fun main() {
// nullable variable a
// with value as null
var a: Int? = null
// using let function
a?.let {
// statement(s) will
// not execute as a is null
print(it)
}
// re-initializing value of a to 2
a = 2
a?.let {
// statement(s) will execute
// as a is not null
print(a)
}
}
输出:
2
解释:
如您所见,当 'a' 的值为 'null' 时,让函数简单地避开代码块。因此,解决了程序员最大的噩梦——NullPointerException。
2. 应用函数
Context object : this
Return value : context object
用例:
顾名思义——“将这些应用于对象”。它可用于对接收器对象的成员进行操作,主要用于初始化成员。
例子:
科特林
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
Company().apply {
// same as founder = “Sandeep Jain”
this.founder = "Sandeep Jain"
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
}
}
3.带函数
Context object : this
Return value : lambda result
用例:
推荐使用 'with' 在上下文对象上调用函数而不提供 lambda 结果。
例子:
科特林
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main() {
val gfg = Company().apply {
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
founder = "Sandeep Jain"
}
// with function
with(gfg) {
// similar to println( "${this.name}" )
println(" $name ")
}
}
输出:
GeeksforGeeks
4.运行函数
Context object : this
Return value : lambda result
'run'函数可以说是 'let' 和 'with' 函数的组合。
用例:
当对象 lambda 包含初始化和返回值的计算时使用。使用 run 我们可以执行空安全调用以及其他计算。
例子:
科特林
class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}
fun main(args: Array) {
println("Company Name : ")
var company: Company? = null
// body only executes if
// company is non-null
company?.run {
print(name)
}
print("Company Name : ")
// re-initialize company
company = Company().apply {
name = "GeeksforGeeks"
founder = "Sandeep Jain"
objective = "A computer science portal for Geeks"
}
// body executes as
// 'company' is non-null
company?.run {
print(name)
}
}
输出:
Company Name :
Company Name : GeeksforGeeks
解释:
当 'company' 值为 null 时,运行的主体将被简单地忽略。当它为非空时,主体执行。
5.还有函数
Context object : it
Return value : context object
用例:
当我们初始化对象成员时,它用于我们必须执行附加操作的地方。
例子:
科特林
fun main() {
// initialized
val list = mutableListOf(1, 2, 3)
// later if we want to perform
// multiple operations on this list
list.also {
it.add(4)
it.remove(2)
// more operations if needed
}
println(list)
}
输出:
[1, 3, 4]
对象引用
作用域函数中有两种对象引用方式:
1.这个
我们可以通过 lambda 接收器关键字this来引用上下文对象。 this关键字在'run'、'with' 和 'apply'函数中执行对象引用。
例子:
科特林
Company().apply {
// same as : name = "GeeksforGeeks"
this.name = "GeeksforGeeks"
this.founder = "Sandeep Jain"
this.objective = "A computer science portal for Geeks"
}
Note: We can exclude this keyword to refer to members of the class.
2.它
'let' 和 'also' 函数将对象的上下文称为lambda 参数。
例子:
科特林
Company().let {
it.name = "GeeksforGeeks"
it.founder = "Sandeep Jain"
it.objective = "A computer science portal for Geeks"
}
返回值
作用域函数可以返回两种类型的返回值:
1. Lambda 结果
如果我们在代码块的末尾写任何表达式,它就会成为作用域函数的返回值。 'let'、'run' 和 'with' 函数的返回值是 lambda 结果。
例子:
科特林
class Company {
var name: String = "GeeksforGeeks"
var founder: String = "Sandeep Jain"
var objective: String = "A computer science portal for Geeks"
}
fun main() {
val founderName: String = with(Company()) {
// 'founder' is returned by 'with' function
founder
}
println("GfG's Founder : $founderName")
}
输出:
GfG's Founder : Sandeep Jain
2. 上下文对象
'apply' 和 'also' 函数返回上下文对象本身。在这种情况下,我们不需要指定返回值。上下文对象会自动返回。
例子:
科特林
class Company {
var name: String = "GeeksforGeeks"
var founder: String = "Sandeep Jain"
var objective: String = "A computer science portal for Geeks"
}
fun main() {
val gfg = Company().apply {
// any statement(s)
}
// gfg is an object of class Company as
// return of apply() is context object
print("GfG's Founder : ${gfg.founder}");
}
输出:
GfG's Founder : Sandeep Jain
概括
- 作用域函数使代码更具可读性、清晰和简洁。
- 对象引用——“this”和“it”。
- 返回值——上下文对象和 lambda 结果。
- let :使用可为空的对象来避免 NullPointerException。
- apply :更改对象配置。
- run:对可为空的对象进行操作,执行 lambda 表达式。
- 也:添加额外的操作。
- with :对非空对象进行操作。