我如何知道 Kotlin 中是否传递了空块?

Hel*_*oCW 3 kotlin

我希望uriHandler.openUri(annotation.item)当我不向 传递block参数 时可以被解雇AnnotatedURLText,并且block()当我向它传递参数时可以被解雇。

但我发现uriHandler.openUri(annotation.item)当我运行 Call A、B 或 C 时并没有被触发,我该如何触发它?

代码1

@Composable
fun AnnotatedURLText(
    ...   
    block: ()->Unit = {}
) {

   val uriHandler = LocalUriHandler.current
   ...

    ClickableText(
        ...
        onClick = { offset ->          
            annotatedText.getStringAnnotations(tag = "URL", start = offset, end = offset)
                .firstOrNull()?.let { annotation ->
                    if (block=={}) {
                        uriHandler.openUri(annotation.item)  //It can't be fired
                    }else{
                        block()
                    }
                }
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

呼叫A

AnnotatedURLText(...)
{
   todo()
}
Run Code Online (Sandbox Code Playgroud)

呼叫B

AnnotatedURLText(...)
Run Code Online (Sandbox Code Playgroud)

呼叫C

AnnotatedURLText(...)
{ 
}
Run Code Online (Sandbox Code Playgroud)

新增内容

致雾大师:谢谢!

我根据你的想法编写了代码2,但出现以下错误。

@Composable 调用只能在 @Composable 函数的上下文中发生

代码2

@Composable
fun AnnotatedURLText(
    ...   
    block: (String) -> Unit = {
        LocalUriHandler.current.openUri(it)  //It cause error
    }
) {
   ...

    ClickableText(
        ...
        onClick = { offset ->          
            annotatedText.getStringAnnotations(tag = "URL", start = offset, end = offset)
                .firstOrNull()?.let { annotation ->  
                    block(annotation.item)
                }
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

cac*_*acs 7

我不认为你可以像这样检查你传入的函数的内容。与其为该参数设置默认值{},为什么不将其设置为null呢?

fun AnnotatedURLText(
    ...   
    block: (() -> Unit)? = null
) {
    ...

    .firstOrNull()?.let { annotation ->
        // run block if it's not null, otherwise open the URI
        block?.invoke() ?: uriHandler.openUri(annotation.item)
    }
Run Code Online (Sandbox Code Playgroud)

block.invoke()与 相同block(),但这样您可以进行空检查。

但不要认为有任何方法可以阻止人们传递block“做错事”的函数!


如果你的block函数打算用它做一些事情annotation.item(所以它的类型确实是(String) -> Unit),那么你可能只使用对uriHandler.openUri作为默认值的引用:

fun AnnotatedURLText(
    ...   
    block: (String) -> Unit = LocalUriHandler.current::openUri
) {
    ...

    .firstOrNull()?.let { annotation ->
        // run block, whether it's the default or a user-provided function
        block(annotation.item)
    }
Run Code Online (Sandbox Code Playgroud)

因此,基本上,我们可以直接获取该对象上uriHandler对该LocalUriHandler.current函数的引用,并将其用作函数参数的默认值,而不是创建一个指向任何内容的局部变量,然后在其上调用函数。我假设你的应用程序是如何编写的,但它应该可以工作!