kotlin - 如何将 `with` 代码转换为 Kotlin 中的完整代码?

标签 kotlin

代码 A 来自 article .

它'用with包裹起来,我希望将其转换为完整的代码,我该怎么办?

顺便说一句,代码 B 是错误的。

代码A

val pxValue = with(LocalDensity.current) { 16.dp.toPx() }

代码B

val s = LocalDensity.current
val pxValue=s.16.dp.toPx()

添加内容:

例如,代码 C 使用 with, 我可以编写完整的代码 D,而不是不使用 with 的代码 C。

代码C

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

with(person) {
    name = "No Name"
    tutorial = "Kotlin tutorials"
}

代码D

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

person.name = "No Name"
person.tutorial = "Kotlin tutorials"

最佳答案

为什么可以将代码C重写为代码D,但不能将代码A重写为代码B?正如您链接的答案也提到的那样,区别在于代码 A 中的 toPxDensity 中声明的 Dp扩展方法。 。它的声明如下:

open fun Dp.toPx(): Float

另一方面,您在代码 C 的 with block 中使用的属性都不是在 Person 中声明的扩展属性。

因此,要调用 toPx,您不仅需要一个 Density 实例作为调度接收器,还需要一个Dp 作为扩展接收者。 (有关调度与扩展接收器的更多信息,请参阅 this)

通过改变隐式接收器 this 含义的作用域函数(例如 with/run),您可以轻松提供这两个接收器:

with(LocalDensity.current) {  // LocalDensity.current: (implicit) dispatch receiver
    16.dp.toPx() // 16.dp: explicit extension receiver
}

可以在不使用作用域函数的情况下提供两个接收器(但不是很直观或方便)。例如,仅出于学术目的,您可以在 Density 上声明其他扩展函数:

fun Density.dpToPx(x: Int) = x.dp.toPx()
fun Density.dpToPx(x: Float) = x.dp.toPx()
fun Density.dpToPx(x: Double) = x.dp.toPx()

这里x.dp.toPx的调度接收者与新声明的Density.toPx的扩展接收者相同,扩展接收者为 x.dp.

然后你可以这样调用:

LocalDensity.current.dpToPx(16)

我强烈建议您在编写实际代码时使用with

关于kotlin - 如何将 `with` 代码转换为 Kotlin 中的完整代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73217182/

相关文章:

android - 如何为 Gson Expose 注释添加支持字段

android - 如何设置 Kotlin 版本

android - 将镜像添加到Firebase存储时出错

android - 您如何使用 espresso 测试操作栏后退按钮?

ios - 无法将 iOS 中常见的 Kotlin 扩展函数用作 Swift 扩展

spring-mvc - 如何正确 Autowiring MockMvc bean

kotlin - 我有一个 Vertx 请求,我需要计算一个外部可见(公共(public))URL

kotlin - Kotlin中的属性和参数有什么区别?

constructor - Kotlin:内部类的构造函数只能用包含类的接收者调用

kotlin - 用于安全施法的智能施法