Kotlin 可以动态为对象绑定一个额外对象吗?

发布于 2022-09-07 19:24:20 字数 780 浏览 17 评论 0

我有一个方法,每次都必须传入一个固定的对象 paint,因为这个函数会被频繁调用,所以我不能在内联函数中创建对象。

inline fun Canvas.drawPoint(
    point: PointF,
    paint: Paint) {

    drawPoint(point.x, point.y, paint)
}

但是我很多地方都会调用这个方法。

          //(Canvas.apply(..,..))
            drawPoint(pointA, pointPaint)
            drawPoint(pointB, pointPaint)
            drawPoint(pointC, pointPaint)
            drawPoint(pointD, pointPaint)

可以看到每次都会传入一个pointPaint对象。
所以我在想有没有类似这样一个功能

        //(Canvas.apply(..,..))
            bind(pointPaint)
            drawPoint(pointA)
            drawPoint(pointB)
            drawPoint(pointC)
            drawPoint(pointD)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往日 2022-09-14 19:24:20

完美符合你要求的方式肯定是没有的,因为 bind 函数不可能改变另一个函数内部的局部变量。

折中的方式也有很多,比如定义一个包级属性:

var drawPaint: Paint? = null

然后原来的函数改为:

inline fun Canvas.drawPoint(
    point: PointF,
    paint: Paint) {

    paint?.let {
        drawPoint(point.x, point.y, it)
    }
}

方便使用还可以再定义一个函数来确保 drawPaint 能被准确的赋值和释放:

fun bindPaint(paint: Paint, action: () -> Unit) {
    drawPaint = paint
    action()
    drawPaint = null
}

这样使用时就是:

// Canvas().apply {
bindPaint(somePaint) {
    drawPoint(x, y)
}

还有一种方式是定义一个包装类,并在其中定义一个包含带接收者 Lambda 表达式的参数的函数(接收者为 Canvas),然后将扩展函数定义到这个类中:

class PointPainter(private val paint: Paint) {
    fun Canvas.drawPoint(rect: RectF) {
        drawPoint(rect.x, rect.y, paint)
    }
}

然后定义含有接收者为这个包装对象 Lambda 参数的函数:

fun bindPointPainter(paint: Paint, drawAction: PointPainter.() -> Unit) {
    PointPainter(paint).drawAction()
}

这样用时更方便一些:

// in canvas.apply block
bindPointPainter(somePaint) {
    drawPoint(rect1)
    drawPoint(rect2)
    // ...
}
橘寄 2022-09-14 19:24:20
    fun test() {
        Canvas().bindPaintDrawPoints(Paint())(
            arrayOf(PointF(1f, 2f),
                PointF(2f, 2f),
                PointF(3f, 2f),
                PointF(4f, 2f))
        )
    }

    fun Canvas.bindPaintDrawPoints(paint: Paint): (Array<PointF>) -> Unit {
        return {
            drawPoints(paint, it)
        }
    }

    fun Canvas.drawPoints(paint: Paint, points: Array<PointF>) {
        for (p in points) {
            this.drawPoint(p.x, p.y, paint)
        }
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文