为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

不负相思意 2018-10-06 15:35:07
我有一个方法,每次都必须传入一个固定的对象 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)
查看完整描述

2 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

    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)

        }

    }


查看完整回答
反对 回复 2018-10-21
?
萧十郎

TA贡献1815条经验 获得超12个赞

完美符合你要求的方式肯定是没有的,因为 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 blockbindPointPainter(somePaint) {
    drawPoint(rect1)
    drawPoint(rect2)    // ...}


查看完整回答
反对 回复 2018-10-21
  • 2 回答
  • 0 关注
  • 1221 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信