如何命名对的组件

鉴于配对 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 

因此,如果您有Pairtypes的实例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}")