【发布时间】:2019-01-03 08:42:31
【问题描述】:
在 Visual Basic 中,我们可以像这样使用 With 表达式:
With theCustomer
.Name = "Coho Vineyard"
.URL = "http://www.cohovineyard.com/"
.City = "Redmond"
End With
我正在寻找这样的东西。在 Kotlin 中可以吗?
【问题讨论】:
在 Visual Basic 中,我们可以像这样使用 With 表达式:
With theCustomer
.Name = "Coho Vineyard"
.URL = "http://www.cohovineyard.com/"
.City = "Redmond"
End With
我正在寻找这样的东西。在 Kotlin 中可以吗?
【问题讨论】:
Kotlin 提供了多个所谓的作用域函数。其中一些使用function literal with receiver,这使得编写与您在Visual Basic 中提供的类似代码成为可能。 with 和 apply 都适用于这种情况。有趣的是with 返回一些任意结果R 而apply 总是返回调用函数的具体接收器。
对于您的示例,让我们考虑这两个函数:
with
使用with,我们可以编写如下代码:
val customer = Customer()
with(customer) {
name = "Coho Vineyard"
url = "http://www.cohovineyard.com/"
city = "Redmond"
}
这里传递给with 的lambda 的最后一个表达式是一个赋值,在Kotlin 中,它返回Unit。您可以将with 调用的结果分配给某个新变量,该变量的类型为Unit。这没有用,而且整个方法也不是很惯用,因为我们必须将声明与 customer 的实际初始化分开。
apply
另一方面,使用apply,我们可以将声明和初始化结合起来,因为它默认返回其接收者:
val customer = Customer().apply {
name = "Coho Vineyard"
url = "http://www.cohovineyard.com/"
city = "Redmond"
}
如您所见,每当您想初始化某个对象时,首选apply(在所有类型上定义的扩展函数)。 Here 的另一个主题是关于 with 和 apply 的区别。
【讨论】:
您可以使用 Kotlin 标准库中的 with 函数,例如:
with(theCustomer) {
name = "Coho Vineyard"
url = "http://www.cohovineyard.com/"
city = "Redmond"
}
with() 返回一些结果。它使代码更干净。
你也可以使用apply扩展功能:
theCustomer.apply {
name = "Coho Vineyard"
url = "http://www.cohovineyard.com/"
city = "Redmond"
}
apply - 在Any 类上声明,它可以在所有类型的实例上调用,它使代码更具可读性。在需要利用对象的实例(修改属性)时使用,表达调用链。
它与 with() 的不同之处在于它返回 Receiver。
【讨论】:
这样的?
with(theCustomer) {
Name = "Coho Vineyard"
URL = "http://www.cohovineyard.com/"
City = "Redmond"
}
但是with 需要不可为空的参数。我建议改用let 或apply。
theCustomer?.apply{
Name = "Coho Vineyard"
URL = "http://www.cohovineyard.com/"
City = "Redmond"
}
或
theCustomer?.let{ customer ->
customer.Name = "Coho Vineyard"
customer.URL = "http://www.cohovineyard.com/"
customer.City = "Redmond"
}
【讨论】:
with 绝对不需要要求非空接收器,它的类型参数T 没有上限。当然,在可空引用上使用它确实会(显然)导致 lambda 具有可空的 this。