Why doesn’t this work? ```import Scratch_12.MyUITa...
# announcements
r
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
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
Yeah but when I have to register 5 different cells I can’t do that, hence my workaround.
r
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
Isn't the issue related to the fact that you're in a scratch file?
r
No, it’s exactly the same in normal code.
r
Yeah it works the same in normal code. My extension function has 2 receivers, I expected the compiler to disambiguate on both.
r
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
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
Thanks for the explaination @kralli!