了解 Kotlin 的必要性
Understanding the need for Kotlin let
我正在尝试理解为什么需要 let。在下面的示例中,我有一个 class 测试函数 giveMeFive:
public class Test() {
fun giveMeFive(): Int {
return 5
}
}
给定以下代码:
var test: Test? = Test()
var x: Int? = test?.giveMeFive()
test = null
x = test?.giveMeFive()
x = test?.let {it.giveMeFive()}
x 设置为 5,然后在 test 设置为 null 后,为 x 调用以下任一语句 return null。鉴于在空引用上调用方法会跳过调用并将 x 设置为空,为什么我还需要使用 let?在某些情况下只是?行不通,需要 let 吗?
此外,如果被调用的函数没有 return 任何东西,那么 ?.将跳过通话,我不需要?。让那里。
如果要链接未在链接类型上定义的函数调用,则需要使用 let
。
假设您的函数定义是这样的:
// Not defined inside the Test class
fun giveMeFive(t: Test) {
return 5
}
现在,如果您有一个可为 null 的 Test
并想在链中调用此函数,则必须使用 let
:
val x = test?.let { giveMeFive(it) }
let()
fun <T, R> T.let(f: (T) -> R): R = f(this)
let() 是一个作用域函数:只要您想为代码的特定范围定义变量但不能超出范围,就可以使用它。让你的代码很好地独立是非常有用的,这样你就没有变量“泄漏”:可以访问它们应该在的地方。
DbConnection.getConnection().let { connection ->
}
// 连接在这里不再可见
let() 也可以用作针对 null 进行测试的替代方法:
val map : Map<String, Config> = ...
val config = map[key]
// config is a "Config?"
config?.let {
// This whole block will not be executed if "config" is null.
// Additionally, "it" has now been cast to a "Config" (no
question mark)
}
Kotlin中的.let{}扩展函数:
将对象引用作为调用.let{}
的参数。
Returns 从 let{}
函数返回的任何非原始数据类型的值。默认情况下,它 returns undefined
的值为 kotlin.Any
class.
包kotlin中的声明:
public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
简单实用演示看看.let{}
扩展函数在Kotlin中是如何工作的
示例代码1:-
val builder = StringBuilder("Hello ")
println("Print 0: $builder")
val returnVal = builder.let { arg ->
arg.append("World")
println("Print 1: $arg")
"Done" // Returnning some string
}
println("Print 2: $builder")
println("Print 3: $returnVal")
示例代码 1 输出:-
Print 0: Hello
Print 1: Hello World
Print 2: Hello World
Print 3: Done
In Sample Code 1:
We created the final object of type StringBuilder with initialization value "Hello ".
In builder.let{}
, the builder object reference will be passed to arg
.
Here, the output Print 2: Hello World
and Print 3: Hello World
means that the builder
and arg
, both are pointing to the same StringBuilder
object-reference
. That's why they both print the same String
value.
In the last line of .let{}
function block, we are returning "Done"
String
value which will be assigned to returnVal
.
*Hence, we get Print 3: Done
output from returnVal
.
示例代码 2:-
val builder = StringBuilder("Hello ")
println("Print 0: $builder")
val returnVal = builder.let { arg ->
arg.append("World")
println("Print 1: $arg")
arg.length
}
println("Print 2: $builder")
println("Print 3: $returnVal") // Now return val is int = length of string.
示例代码 2 输出:-
Print 0: Hello
Print 1: Hello World
Print 2: Hello World
Print 3: 11
In Sample Code 2:
What's difference:
In the last line of .let{}
function block, we are returning the Int
value equals to the length of StringBuilder object arg
whose value at this line of code is "Hello World"
. So length = 11
of type Int
will be assigned to returnVal
.
*Hence, we get Print 3: 11
as output from returnVal
.
也试试这些:-
- .运行() {}
- .apply() {}
- with(obj) {}
- .also() {}
编码愉快...
fun T.let(f: (T) -> R): R = f(this)
.let 块在多线程中不等于
验证值 x? =空
if(x == null) {
}
和
x?.let{
}
.let 块是线程安全的
我正在尝试理解为什么需要 let。在下面的示例中,我有一个 class 测试函数 giveMeFive:
public class Test() {
fun giveMeFive(): Int {
return 5
}
}
给定以下代码:
var test: Test? = Test()
var x: Int? = test?.giveMeFive()
test = null
x = test?.giveMeFive()
x = test?.let {it.giveMeFive()}
x 设置为 5,然后在 test 设置为 null 后,为 x 调用以下任一语句 return null。鉴于在空引用上调用方法会跳过调用并将 x 设置为空,为什么我还需要使用 let?在某些情况下只是?行不通,需要 let 吗?
此外,如果被调用的函数没有 return 任何东西,那么 ?.将跳过通话,我不需要?。让那里。
如果要链接未在链接类型上定义的函数调用,则需要使用 let
。
假设您的函数定义是这样的:
// Not defined inside the Test class
fun giveMeFive(t: Test) {
return 5
}
现在,如果您有一个可为 null 的 Test
并想在链中调用此函数,则必须使用 let
:
val x = test?.let { giveMeFive(it) }
let()
fun <T, R> T.let(f: (T) -> R): R = f(this)
let() 是一个作用域函数:只要您想为代码的特定范围定义变量但不能超出范围,就可以使用它。让你的代码很好地独立是非常有用的,这样你就没有变量“泄漏”:可以访问它们应该在的地方。
DbConnection.getConnection().let { connection ->
}
// 连接在这里不再可见
let() 也可以用作针对 null 进行测试的替代方法:
val map : Map<String, Config> = ...
val config = map[key]
// config is a "Config?"
config?.let {
// This whole block will not be executed if "config" is null.
// Additionally, "it" has now been cast to a "Config" (no
question mark)
}
Kotlin中的.let{}扩展函数:
将对象引用作为调用
.let{}
的参数。Returns 从
let{}
函数返回的任何非原始数据类型的值。默认情况下,它 returnsundefined
的值为kotlin.Any
class.
包kotlin中的声明:
public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
简单实用演示看看.let{}
扩展函数在Kotlin中是如何工作的
示例代码1:-
val builder = StringBuilder("Hello ")
println("Print 0: $builder")
val returnVal = builder.let { arg ->
arg.append("World")
println("Print 1: $arg")
"Done" // Returnning some string
}
println("Print 2: $builder")
println("Print 3: $returnVal")
示例代码 1 输出:-
Print 0: Hello
Print 1: Hello World
Print 2: Hello World
Print 3: Done
In Sample Code 1:
We created the final object of type StringBuilder with initialization value "Hello ".
In
builder.let{}
, the builder object reference will be passed toarg
.Here, the output
Print 2: Hello World
andPrint 3: Hello World
means that thebuilder
andarg
, both are pointing to the sameStringBuilder
object-reference
. That's why they both print the sameString
value.In the last line of
.let{}
function block, we are returning"Done"
String
value which will be assigned toreturnVal
.*Hence, we get
Print 3: Done
output fromreturnVal
.
示例代码 2:-
val builder = StringBuilder("Hello ")
println("Print 0: $builder")
val returnVal = builder.let { arg ->
arg.append("World")
println("Print 1: $arg")
arg.length
}
println("Print 2: $builder")
println("Print 3: $returnVal") // Now return val is int = length of string.
示例代码 2 输出:-
Print 0: Hello
Print 1: Hello World
Print 2: Hello World
Print 3: 11
In Sample Code 2:
What's difference:
In the last line of
.let{}
function block, we are returning theInt
value equals to the length of StringBuilder objectarg
whose value at this line of code is"Hello World"
. So length =11
of typeInt
will be assigned toreturnVal
.*Hence, we get
Print 3: 11
as output fromreturnVal
.
也试试这些:-
- .运行() {}
- .apply() {}
- with(obj) {}
- .also() {}
编码愉快...
fun
.let 块在多线程中不等于
验证值 x? =空
if(x == null) {
}
和
x?.let{
}
.let 块是线程安全的