Kotlin:采用 vararg lamba-with-receiver 的高阶函数,其中接收器采用参数
Kotlin: higher-order function taking vararg lamba-with-receiver, where the receiver takes arguments
我正在尝试将 Java 构建器的层次结构包装在 Kotlin 类型安全构建器中。层次结构由以下构建器(及其目标)组成:
- FigureBuilder(图)
- LayoutBuilder(布局)
- TraceBuilder(跟踪)
在 Java 中,FigureBuilder 有一个方法接受 Layout,另一个方法接受 n 条轨迹,使用名为 addTraces() 的可变参数方法:
addTraces(Trace... traces)
Java中的组装过程基本上就是
Figure f = Figure.builder()
.layout(
Layout.builder()
.title("title")
.build())
.addTraces(
ScatterTrace.builder()
.name("my series")
.build())
.build();
在 Kotlin 中,我有创建图形生成器和布局生成器的代码,但我被困在跟踪生成器上。到目前为止,我的代码如下所示:
val figure = figure {
layout {title("Wins vs BA")}
addTraces(
ScatterTrace.builder(x, y)
.name("Batting avg.").build()
)
}
fun figure(c: FigureBuilder.() -> Unit) : Figure {
val builder = Figure.builder()
c(builder)
return builder.build()
}
fun FigureBuilder.layout(c: Layout.LayoutBuilder.() -> Unit) {
layout(Layout.builder().apply(c).build())
}
// won't compile: ScatterTrace.builder() requires 2 args
fun FigureBuilder.traces(vararg c: ScatterTrace.ScatterBuilder.() -> Unit) {
c.forEach {
val builder = ScatterTrace.builder()
it(builder)
addTraces(builder.build())
}
}
我完全不确定最后一个函数是否可以编译,但直接阻塞的问题是 ScatterTrace.builder() 有两个参数和
我不知道如何将它们传递给 lambda。
非常感谢
奇怪的是,在 Java 中您可以创建不带参数的 ScatterTrace.builder
,但在 Kotlin 中您需要两个参数来构造它。也许一个一个地应用痕迹会更好?
fun FigureBuilder.traces(x: Int, y: Int, c: ScatterTrace.ScatterBuilder.() -> Unit) {
val builder = ScatterTrace.builder(x, y)
c(builder)
addTraces(builder.build())
}
val figure = figure {
layout { title("Wins vs BA") }
addTraces(
trace(x, y) { name("Batting avg.") },
trace(x, y) { name("Batting avg. 2") },
trace(x, y) { name("Batting avg. 3") }
)
}
fun FigureBuilder.traces(vararg c: ScatterTrace.ScatterBuilder.() -> Unit) {
addTraces(
*c.map {
val builder = ScatterTrace.builder()
builder.build()
}.toTypedArray()
)
}
应该满足您对可变参数要求的要求。
我正在尝试将 Java 构建器的层次结构包装在 Kotlin 类型安全构建器中。层次结构由以下构建器(及其目标)组成:
- FigureBuilder(图)
- LayoutBuilder(布局)
- TraceBuilder(跟踪)
在 Java 中,FigureBuilder 有一个方法接受 Layout,另一个方法接受 n 条轨迹,使用名为 addTraces() 的可变参数方法:
addTraces(Trace... traces)
Java中的组装过程基本上就是
Figure f = Figure.builder()
.layout(
Layout.builder()
.title("title")
.build())
.addTraces(
ScatterTrace.builder()
.name("my series")
.build())
.build();
在 Kotlin 中,我有创建图形生成器和布局生成器的代码,但我被困在跟踪生成器上。到目前为止,我的代码如下所示:
val figure = figure {
layout {title("Wins vs BA")}
addTraces(
ScatterTrace.builder(x, y)
.name("Batting avg.").build()
)
}
fun figure(c: FigureBuilder.() -> Unit) : Figure {
val builder = Figure.builder()
c(builder)
return builder.build()
}
fun FigureBuilder.layout(c: Layout.LayoutBuilder.() -> Unit) {
layout(Layout.builder().apply(c).build())
}
// won't compile: ScatterTrace.builder() requires 2 args
fun FigureBuilder.traces(vararg c: ScatterTrace.ScatterBuilder.() -> Unit) {
c.forEach {
val builder = ScatterTrace.builder()
it(builder)
addTraces(builder.build())
}
}
我完全不确定最后一个函数是否可以编译,但直接阻塞的问题是 ScatterTrace.builder() 有两个参数和 我不知道如何将它们传递给 lambda。
非常感谢
奇怪的是,在 Java 中您可以创建不带参数的 ScatterTrace.builder
,但在 Kotlin 中您需要两个参数来构造它。也许一个一个地应用痕迹会更好?
fun FigureBuilder.traces(x: Int, y: Int, c: ScatterTrace.ScatterBuilder.() -> Unit) {
val builder = ScatterTrace.builder(x, y)
c(builder)
addTraces(builder.build())
}
val figure = figure {
layout { title("Wins vs BA") }
addTraces(
trace(x, y) { name("Batting avg.") },
trace(x, y) { name("Batting avg. 2") },
trace(x, y) { name("Batting avg. 3") }
)
}
fun FigureBuilder.traces(vararg c: ScatterTrace.ScatterBuilder.() -> Unit) {
addTraces(
*c.map {
val builder = ScatterTrace.builder()
builder.build()
}.toTypedArray()
)
}
应该满足您对可变参数要求的要求。