如何命名对的组件
鉴于配对 val coordinates = Pair(2, 3)
,是否有可能命名每个值,所以我可以做一些像coordinates.x
返回2
? 或者是coordinates.first
唯一的方法来访问第一个值?
这不被支持。 你应该为此写一个包装(数据)类,或者你可以使用Kotlin解构声明:
val (x, y) = coordinates println("$x;$y")
在这里看到更多。
Pair
在Kotlin stdlib中的定义如下:
public data class Pair( public val first: A, public val second: B ) : Serializable
因此,如果您有Pair
types的实例p
,则可以仅以p.first
访问第一个属性。 但是,您可以使用这样的解构声明 :
val (x, y) = p
这是可能的,因为Pair
是一个data class
。 数据类的主构造函数的每个参数都得到一个componentX()
方法,其中X
是参数的索引。 所以上面的调用可以这样expression:
val x = p.component1() val y = p.component2()
这使得它与参数的实际名称完全无关。
但是,如果你想写px
,你必须先创建你自己的数据类(或者使用一个库):
data class Point(val x : Double, val y : Double)
另一种解决方案是为Pair
定义一个带有有意义扩展的object
,并使用with(...) { ... }
将这些扩展带入上下文中。
object PointPairs { val Pair.x get() = first val Pair<*, Y>.y get() = second }
用法:
val point = Pair(2, 3) with(PointPairs) { println(point.x) }
这使您可以为同一types设置几组扩展,并在适当的地方使用。
我想提出一个替代方案,如果仅在一定范围内需要重命名,则应该应用该替代方案。
您可以创建一个简单的扩展高级函数,使作用域中的命名成为一个lambda参数:
fun Pair.named(block: (F, S) -> Unit) = block(first, second)
现在,一个Pair
可以用一个lambda来调用,这个lambda是通过其在调用者站点上可以命名的组件来调用的:
val pair = Pair(2, 3) pair.named { x, y -> println("my pair: ($x,$y)") }
甚至可以应用invoke
约定 :
operator fun Pair.invoke(block: (F, S) -> Unit) = block(first, second)
现在, Pair
可以直接调用:
val pair = Pair(2, 3) pair { x, y -> println("my pair: ($x,$y)") }
Kotlin的文件说:
标准库提供Pair和Triple。 但是,在大多数情况下,命名数据类是更好的设计选择,因为它们通过为属性提供有意义的名称使代码更具可读性。
因为Pair
是最后的,所以不幸的是不能inheritance它,但是我建议创建一个专门的类Point
:
data class Point(var x: T, var y: T)
代表一个观点。 这种方式,无论你使用它,你总是被迫使用有意义的名字访问它。
用它:
val myPoint = Point(1.0, 2.0) println("This is the horizontal coordinate: ${myPoint.x}")
- 为什么我的RxJava设置阻止我的UI线程? 使用BluetoothAdapter.startLeScan回调
- 如何在Kotlin for Android上使用“setTextColor(hexaValue)”,