这是一个非官方概述这些名称的由来。
let
let https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html受到函数式编程世界的启发。根据维基百科 https://en.wikipedia.org/wiki/Let_expression
“let”表达式将函数定义与受限范围相关联
在像 Haskell 这样的 FP 语言中,你可以使用let
将值绑定到受限范围内的变量,如下所示
aaa = let y = 1+2
z = 4+6
in y+z
Kotlin 中的等效(尽管过于复杂)代码是
fun aaa() = (1+2).let { y ->
(4+6).let { z ->
y + z
}
}
典型用法let
是将某些计算的结果绑定到一个范围而不“污染”外部范围。
creater.createObject().let {
if (it.isCorrect && it.shouldBeLogged) {
logger.log(it)
}
}
// `it` is out of scope here
with
The with https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/with.html函数的灵感来自于with
语言由像这样的语言构造Delphi http://www.delphibasics.co.uk/RTL.asp?Name=with or 视觉基础 https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/with-end-with-statement(可能还有许多其他人)在哪里
with关键字是Delphi提供的一种方便引用的方法
复杂变量的元素,例如记录或对象。
myObject.colour := clRed;
myObject.size := 23.5;
myObject.name := 'Fred';
可以重写:
with myObject do
begin
colour := clRed;
size := 23.5;
name := 'Fred';
end;
等效的 Kotlin 是
with(myObject) {
color = clRed
size = 23.5
name = "Fred"
}
apply
apply https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html在里程碑阶段 (M13) 相对较晚的时间被添加到 stdlib。你可以看到this https://stackoverflow.com/a/28659271/6153062015 年的一个问题,用户要求提供这样的功能,甚至建议稍后使用的名称“apply”。
在问题中https://youtrack.jetbrains.com/issue/KT-6903 https://youtrack.jetbrains.com/issue/KT-6903 and https://youtrack.jetbrains.com/issue/KT-6094 https://youtrack.jetbrains.com/issue/KT-6094你可以看到命名的讨论。替代品如build
and init
被提议,但名称apply
丹尼尔·沃多皮安 (Daniil Vodopian) 提出的方案最终获胜。
apply
类似于with
因为它可以用来初始化构造函数之外的对象。这就是为什么,在我看来,apply
不妨命名with
。然而作为with
首先被添加到 stdlib 中,Kotlin 开发人员决定不破坏现有代码并以不同的名称添加它。
讽刺的是,Xtend 语言提供了所谓的带运算符=> http://jnario.org/org/jnario/spec/tests/integration/UsingXtendSWithOperatorSpec.html这基本上与apply
.
also
also https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/also.html甚至晚于apply
,即1.1版本中。再次,https://youtrack.jetbrains.com/issue/KT-6903 https://youtrack.jetbrains.com/issue/KT-6903包含讨论。该功能基本上是这样的apply
除了它需要一个常规的 lambda(T) -> Unit
而不是扩展 lambdaT.() -> Unit
.
提议的名称包括“applyIt”、“applyLet”、“on”、“tap”、“touch”、“peek”、“make”。但“also”获胜,因为它不与任何关键字或其他 stdlib 函数冲突,而且它的用法(或多或少)读起来像英语句子。
Example
val object = creater.createObject().also { it.initiliaze() }
读起来有点像
创建者,创建对象并also初始化它!
其他 stdlib 函数的用法读起来有点像英语句子,包括takeIf https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/take-if.html and takeUnless https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/take-unless.html1.1 版本中也添加了这些内容。
run
最后,run https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html函数实际上有两个签名。第一个fun <R> run(block: () -> R): R
只需要一个 lambda 并且runs它。它主要用于将 lambda 表达式的结果分配给顶级属性
val logger = run {
val name = System.property("logger_name")
Logger.create(name)
}
第二个签名fun <T, R> T.run(block: T.() -> R): R
是一个扩展函数,它采用扩展 lambda 作为参数,并且出于对称原因似乎也被命名为“run”。它也“运行”一个 lambda,但是是在扩展接收器的上下文中
val result = myObject.run {
intitialize()
computeResult()
}
我不知道这个命名有任何历史原因。