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)
}
}

TA貢獻1815條經驗 獲得超13個贊
完美符合你要求的方式肯定是沒有的,因為 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) // ...}
- 2 回答
- 0 關注
- 1294 瀏覽
添加回答
舉報