Kotlin Jetpack Compose:调用返回Lambda的函数时括号问题解析
background函数调用的疑问解答 以下代码基于Roman Y.的实现,针对三种不同调用方式的疑问逐一解答:
疑问1:Code A 使用background(appState)() {...}可正常运行,为何无法省略中间的括号()?
先看background函数的返回值类型:它是一个带@Composable注解的函数类型——@Composable (@Composable () -> Unit) -> Unit。简单说,background(appState)执行后,返回的是另一个需要接收lambda参数的Composable函数。
在Kotlin语法里,链式调用这种返回函数的方法时,必须先用()执行外层函数拿到返回的函数实例,再用{...}给这个返回的函数传参数。如果省略中间的(),编译器会错误地把{...}当成background函数的第二个参数,但background本身只接受appState这一个参数,语法不匹配就会报错。
疑问2:Code B 使用background(appState) {...}调用时执行失败,原因是什么?
background函数的定义明确只接收appState这一个参数,返回的是另一个Composable函数。而background(appState) {...}的写法,相当于把{...}当成background的第二个实参传递,但background根本没有第二个参数,编译器找不到匹配的函数签名,直接触发语法错误,自然执行失败。
疑问3:Code C 先将background(appState)赋值给变量aa,再通过aa{...}调用可正常运行,这是为什么?
val aa = background(appState)这行代码先执行了background(appState),拿到了它返回的接收lambda的Composable函数实例,并把这个函数引用存在aa变量里。之后的aa{...}就是直接调用这个函数实例,把{...}作为它的lambda参数传递,完全符合Kotlin函数调用的语法规则,所以能正常运行。
Code A
@Composable fun NiaApp( windowSizeClass: WindowSizeClass, appState: NiaAppState = rememberNiaAppState(windowSizeClass) ) { NiaTheme { background(appState)() { Scaffold( ... ) { padding -> } } } } @Composable fun background(appState: NiaAppState): @Composable (@Composable () -> Unit) -> Unit = when (appState.currentDestination?.route) { ForYouDestination.route -> { content -> NiaGradientBackground(content = content) } else -> { content -> NiaBackground(content = content) } }
Code B
@Composable fun NiaApp( windowSizeClass: WindowSizeClass, appState: NiaAppState = rememberNiaAppState(windowSizeClass) ) { NiaTheme { background(appState){ Scaffold( ... ) { padding -> } } } } ...
Code C
@Composable fun NiaApp( windowSizeClass: WindowSizeClass, appState: NiaAppState = rememberNiaAppState(windowSizeClass) ) { val aa=background(appState) NiaTheme { aa{ Scaffold( ... ) { padding -> } } } } ...
内容的提问来源于Stack Exchange,提问作者HelloCW

