为何无法在对应作用域内调用类的扩展函数?
为何无法在对应作用域内调用类的扩展函数?
哈哈,这个问题我之前踩过坑!其实是Kotlin里「成员扩展函数」的调用规则在搞怪,我给你掰扯清楚~
你在SampleClass内部定义的fun NavGraphBuilder.navGraph(),本质是成员扩展函数:它既是SampleClass的成员函数,同时又是给NavGraphBuilder加的扩展函数。这意味着调用它必须同时满足两个前提:
- 要有一个
SampleClass的实例(毕竟它是类的成员,要么要访问类的内部状态,要么就是属于这个类的成员范畴) - 要处于
NavGraphBuilder的作用域中(或者手里有一个NavGraphBuilder的实例当接收者)
你现在写的sampleClass.navGraph(),相当于告诉编译器:“我要调用sampleClass这个实例的普通成员函数navGraph()”,但实际上sampleClass根本没有这个普通成员函数——这个函数是给NavGraphBuilder加的扩展,所以编译器自然找不到,就抛出“Unresolved reference”的错误了。
接下来给你两种解决思路,看你的需求选:
情况1:扩展函数不需要依赖SampleClass的内部成员
如果navGraph()的逻辑完全不需要用到SampleClass里的属性或函数,那最简单的办法就是把它从SampleClass内部移出来,改成顶级扩展函数:
// 直接放在SampleClass外面(比如同一个文件的顶层位置) fun NavGraphBuilder.navGraph() { // 你的导航图逻辑代码 } // 然后在NavHost里直接调用就好 val sampleClass = SampleClass() NavHost(navController = rememberNavController(), startDestination = Player) { navGraph() // 因为当前lambda的作用域就是NavGraphBuilder,直接调用就行 }
情况2:扩展函数必须依赖SampleClass的内部成员
如果navGraph()的逻辑必须用到SampleClass里的属性或函数,那你需要在NavGraphBuilder的作用域里,同时引入SampleClass的上下文。用Kotlin的run函数就能轻松实现:
class SampleClass { // 假设扩展函数需要用到这个内部属性 private val navConfig = "Some config from SampleClass" fun NavGraphBuilder.navGraph() { // 这里可以直接访问navConfig println(navConfig) // 你的导航图逻辑 } } // 调用方式调整成这样 val sampleClass = SampleClass() NavHost(navController = rememberNavController(), startDestination = Player) { // 用sampleClass.run把上下文切换到SampleClass,同时当前lambda的作用域还是NavGraphBuilder sampleClass.run { navGraph() // 现在编译器就能找到这个函数了:两个上下文都满足了 } }
另外还有一种替代方案:把SampleClass的实例作为参数传给扩展函数,改成带参数的顶级扩展:
// 顶级扩展函数,接收SampleClass实例作为参数 fun NavGraphBuilder.navGraph(sample: SampleClass) { // 访问sample的内部成员 println(sample.navConfig) } // 调用时传参就行 NavHost(...) { navGraph(sampleClass) }
这个方案也能解决问题,具体选哪种就看你的代码结构和需求啦~
备注:内容来源于stack exchange,提问作者Nito
相关产品推荐
相关产品推荐

