I see Code B frequently, and I see Code A seldom.
Is Code A correct?
Is block: (canvas: Canvas) -> Unit
equivalent to block: Canvas.() -> Unit
in Kotlin?
Code A
fun DrawScope.drawNormal(block: (canvas: Canvas) -> Unit) {
drawIntoCanvas {
block(it)
}
}
Code B
fun DrawScope.drawNormal(block: Canvas.() -> Unit) {
drawIntoCanvas {
block(it)
}
}
CodePudding user response:
Code A declare a function who takes a Canvas as parameters.
You'll be able to use Canvas using it
or by naming it.
drawNormal { canvas ->
// do whatever you want with canvas
}
In code B you are using (like @gidds said) a function literal with receiver. You provide a scope where the anonymous function will be running. So in the anonymous function, the this
will be the canvas.
drawNormal {
// no parameters, you can simply use all canvas functions in this block
}
Both approach are good but it depends on what you are trying to achieve.
It's like scoped functions with let
and apply
The code A will be better if you just want to get canvas attributes like width and length to build another things or do some actions with it.
The code B will be better if you want to modify the canvas reference (like modifying width and length)
CodePudding user response:
They are not equivalent from the point of view of the caller of your function.
In Code A, block
is a function that takes the Canvas
as an argument. This means that the caller of drawNormal
will access it as it
or via a named parameter in the lambda:
drawNormal {
it.rotate(90f)
}
drawNormal { canvas ->
canvas.rotate(90f)
}
In Code B, block
is a function that takes a Canvas
as a receiver. This means that the caller will access it as this
or call functions from Canvas
directly:
drawNormal {
this.rotate(90f)
rotate(90f)
}
Both are equally correct. It depends on the experience you want to provide to your caller.