https://kotlinlang.org logo
#announcements
Title
# announcements
r

ribesg

11/04/2020, 1:54 PM
Why doesn’t this work?
Copy code
import Scratch_12.MyUITableViewCell.Companion.register

class UITableView

class MyUITableViewCell {
    companion object {
        fun UITableView.register() {}
    }
}

val tableView = UITableView()
with(tableView) {
    MyUITableViewCell.register()
}
The IDE adds the import but the call to
register
is still red and it says it cannot find it and suggests to import it, which does nothing as it’s already imported (example class names are relevant to the use case).
My workaround is to rename
register
to
registerMyCell
and call
tableView.registerMyCell()
but I find the way I wrote it in my post to be more clear and better typed
r

Rob Elliot

11/04/2020, 2:02 PM
Should be
Copy code
import Scratch_12.MyUITableViewCell.Companion.register

class UITableView
class MyUITableViewCell {
    companion object {
        fun UITableView.register() {}
    }
}
val tableView = UITableView()
with(tableView) {
    register()
}
Within the
with
block
this
is the
tableView
. And
register
is an extension function on
UITableView
, so you would normally call it as
tableView.register()
- so in a
with
block you call it as just
register()
.
r

ribesg

11/04/2020, 2:08 PM
Yeah but when I have to register 5 different cells I can’t do that, hence my workaround.
r

Rob Elliot

11/04/2020, 2:13 PM
Is this what you want:
Copy code
class UITableView
class MyUITableViewCell {
    companion object {
        fun register(tableView: UITableView) {}
    }
}
class MyOtherUITableViewCell {
    companion object {
        fun register(tableView: UITableView) { }
    }
}
val tableView = UITableView()
with(tableView) {
    MyUITableViewCell.register(this)
    MyOtherUITableViewCell.register(this)
}
Are you trying to have multiple
fun UITableView.register()
extension functions on the companion objects of multiple Cell class companion objects, and get the compiler to disambiguate between them by prefacing the call with the Cell class name? If so I don’t think that is possible.
l

louiscad

11/04/2020, 2:25 PM
Isn't the issue related to the fact that you're in a scratch file?
r

Rob Elliot

11/04/2020, 2:29 PM
No, it’s exactly the same in normal code.
r

ribesg

11/04/2020, 2:42 PM
Yeah it works the same in normal code. My extension function has 2 receivers, I expected the compiler to disambiguate on both.
r

Rob Elliot

11/04/2020, 2:43 PM
Pretty sure an extension function can only have one receiver. The whole point is that you are pretending to add a function to an existing type in much the same way as if you were editing that type.
k

kralli

11/04/2020, 3:05 PM
You would have to swap your dispatcher and receiver as your method specifies
MyUITableViewCell
as dispatcher and
UITableView
as receiver:
Copy code
class UITableView

class MyUITableViewCell {
    companion object {
        fun UITableView.register() {}
    }
}

val tableView = UITableView()
with(MyUITableViewCell) {
    tableView.register()
}
You are to judge whether or not you like this.
The rules for dispatcher and receiver basically are the following: • top-level functions like
fun example()
do not have a dispatcher nor receiver • extension functions like
fun Receiver.example()
have an explicit receiver but no dispatcher • functions of classes like
class Receiver { fun example() }
have an implicit receiver but no dispatcher • extension functions in classes like
class Dispatcher { fun Receiver.example() }
have both an explicit receiver as well as a dispatcher Dispatchers always have to be bound implicitly (e.g. using
with
) and receivers specified explicitly (i.e. calling the function on the object).
r

ribesg

11/04/2020, 5:05 PM
Thanks for the explaination @kralli!
2 Views