申请和之间有什么区别。据我所知,以下代码执行相同的操作:
应用
val person = Person().apply {
name = "Tony Stark"
age = 52
// More such stuff
}
同时
val person = Person().also {
it.name = "Tony Stark"
it.age = 52
// More such stuff
}
有什么不同,我应该使用一个吗?此外,是否有一些情况下,一个人会工作,另一个不会?
答案 0 :(得分:20)
TL; DR差异
also
函数接收一个lambda,T
在实现中传递给它,因此在lambda中你引用一个名称(默认为it
),可以重命名{ otherName -> ...}
)。
val person = Person().also {
it.name = "Tony Stark"
}
另一方面,在apply
中,使用了函数文字 with receiver ,因此在传递的lambda中,您不必添加额外的前缀来访问其成员,如你在下面看到。接收者可以由this
引用。
val person = Person().apply {
name = "Tony Stark"
}
宣言:
inline fun <T> T.also(block: (T) -> Unit): T (source)
使用this
(接收方)值作为参数调用指定的功能块,并返回this
(接收方)值。
宣言:
inline fun <T> T.apply(block: T.() -> Unit): T (source)
使用this
值作为接收器调用指定的功能块,并返回this
(接收方)值。
此thread中解释了用法示例。
答案 1 :(得分:15)
简短回答: also
是出于语义原因而引入的。
答案很长:
如果您使用apply
,请始终使用this
来指向接收方。
val person = Person().apply {
name = "Tony Stark" // this. can be omitted
age = 52 // this. can be omitted
// ...
}
这样你就不必重复几次了,如下所示:
person.name = "Tony Stark"
person.age = 52
如果块变长,您可能想要给this
一个名字。这就是also
被引入的原因。现在,您可以通过it
或显式名称来引用接收器。如果您想在之前使用其他名称(在本例中为person
),这将非常有用:
val person = Person().also { newPerson ->
newPerson.name = "Tony Stark"
newPerson.age = 52
// ...
}
因此,根据您的代码的可读性,您可以随时使用其中一种。
答案 2 :(得分:5)
由您决定使用哪个。但是,在Kotlinlang的网站https://kotlinlang.org/docs/reference/scope-functions.html中,有一个约定使用它们
还将也用于不会改变对象的其他操作,例如记录或打印调试信息。
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
应用的常见情况是对象配置。
val adam = Person("Adam").apply {
age = 32
city = "London"
}
println(adam)
答案 3 :(得分:1)
上面给出的答案有点意义,但并不多。我没有正确理解它,但我想在这里添加问题。
在Standard.kt中,这是两种方法的实际实现。
申请
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
也适用于
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
除了一行之外,这两种方法几乎相同。只有经过解释后,我才看到了不同之处。像Kotlin这样的功能语言对于像我这样的Java思想的初级开发人员来说真的很有挑战性。