如何命名对的组件

Dic*_*cas 8 tuples kotlin

鉴于 val coordinates = Pair(2, 3),是有可能命名每个值,因此我可以这样做coordinates.x2?或者是coordinates.first获取第一个值的唯一方法?

dni*_*Hze 9

这不受支持.您应该为此目的编写一个包装器(数据)类,或者您可以使用Kotlin解构声明:

val (x, y) = coordinates
println("$x;$y")
Run Code Online (Sandbox Code Playgroud)

在这里查看更多.


s1m*_*nw1 7

我想提出一个替代方案,如果仅在特定范围内需要重命名,则应应用该替代方案。

您可以创建一个简单的扩展高阶函数,在范围内启用命名,作为 lambda 参数传递:

fun <F, S> Pair<F, S>.named(block: (F, S) -> Unit) = block(first, second)
Run Code Online (Sandbox Code Playgroud)

现在,Pair可以使用 lambda 调用 a,该 lambda 使用其在调用方站点上可命名的组件进行调用:

val pair = Pair(2, 3)
pair.named { x, y ->
    println("my pair: ($x,$y)")
}
Run Code Online (Sandbox Code Playgroud)

甚至可以应用invoke约定

operator fun<F, S> Pair<F, S>.invoke(block: (F, S) -> Unit) = block(first, second)
Run Code Online (Sandbox Code Playgroud)

现在,Pair可以直接调用:

val pair = Pair(2, 3)
pair { x, y ->
    println("my pair: ($x,$y)")
}
Run Code Online (Sandbox Code Playgroud)


hot*_*key 7

另一个解决方案是定义一个object有意义的扩展, Pair<A, B>并将这些扩展用于上下文with(...) { ... }.

object PointPairs {
    val <X> Pair<X, *>.x get() = first
    val <Y> Pair<*, Y>.y get() = second
}
Run Code Online (Sandbox Code Playgroud)

用法:

val point = Pair(2, 3)

with(PointPairs) {
    println(point.x)
}
Run Code Online (Sandbox Code Playgroud)

这允许您为相同类型提供多组扩展,并在适当的地方使用它们.


msr*_*rd0 5

PairKotlin stdlib 的定义如下:

public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
) : Serializable
Run Code Online (Sandbox Code Playgroud)

因此,如果您有一个p类型的实例Pair,则只能访问第一个属性p.first.但是,您可以使用如下的解构声明:

val (x, y) = p
Run Code Online (Sandbox Code Playgroud)

这是可能的,因为Pairdata class.数据类的主要构造函数的每个参数都获取一个componentX()方法,其中X是参数的索引.所以上面的调用可以这样表达:

val x = p.component1()
val y = p.component2()
Run Code Online (Sandbox Code Playgroud)

这使它完全独立于参数的实际名称.

但是,如果您希望能够编写p.x,则必须继续创建自己的数据类(或使用库):

data class Point(val x : Double, val y : Double)
Run Code Online (Sandbox Code Playgroud)