android - Kotlin `by` 关键字是否适用于可为空的委托(delegate)?

标签 android kotlin delegation

我对 Kotlin 编译器功能和 by 感到非常兴奋特别是 - 它节省了生成凝胶代码的时间:

https://kotlinlang.org/docs/reference/delegation.html

但我希望代表成为 可以为空 并委托(delegate)代码首先检查它是否为空,如果是则返回:

interface Base {
    val message: String
    fun print()
}

class BaseImpl(val x: Int?) : Base {
    override val message = "BaseImpl: x = $x"
    override fun print() { println(message) }
}

class Derived(b: Base?) : Base by b {
    // This property is not accessed from b's implementation of `print`
    override val message = "Message of Derived"
}

fun main() {
    val b = BaseImpl(10)
    val derived = Derived(b)
    derived.print()
    println(derived.message)
}

编译时 ^ 我得到 Type mismatch: inferred type is Base? but Base was expected .

Kotlin 还有可能吗?

更详细地说,我希望 Kotlin 编译器在 https://developer.android.com/reference/android/webkit/WebChromeClient 中生成对包装 impl ( extWebChromeClient ) 的转发调用如下:
private WebChromeClient intWebChromeClient = new WebChromeClient()
  {
    @Override
    public void onReceivedTitle(WebView view, String title)
    {
      if (extWebChromeClient != null)
      {
        extWebChromeClient.onReceivedTitle(view, title);
      }
    }
 ...

最佳答案

您可以使用 dynamic proxies 自己制作。 ,虽然我不会真的推荐它。请注意,对于非 void方法没有办法要求覆盖它们。下面的实现只是无条件地为它们抛出异常,但是您仍然可以将它们称为非空 x .

inline fun <reified T : Any> nullableProxy(x: T?): T {
    val handler = InvocationHandler { _, method, args ->
        if (method.returnType == Void.TYPE) {
            if (x != null) {
                method.invoke(x, *(args ?: arrayOf()))
            }
        } else 
            throw UnsupportedOperationException("Non-void method")
    }

    return Proxy.newProxyInstance(
        T::class.java.classLoader,
        arrayOf(T::class.java),
        handler) as T
}

class Derived(b: Base?) : Base by nullableProxy(b)

这也不会像直接实现方法那样执行。

关于android - Kotlin `by` 关键字是否适用于可为空的委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55358582/

相关文章:

android - 从 SD 卡中删除音频

android - 谷歌地图不显示在手机上,但在模拟器中可见

kotlin - 可观察到在没有订阅者时缓冲项目,然后在订阅时发出它们并清除缓冲区?

javascript - 如何在不阻止 jQuery 中的默认设置的情况下阻止父级的委托(delegate)处理程序?

java - 创建 FragmentTabHost 导致一些麻烦

java - Kotlin:用 Pair<Int, Int> 调用 (Int, Int) -> Int 的惯用方式?

android - Unresolved reference - Activity 无法识别 android studio v4 中的合成导入

swift - 如何识别委托(delegate)对象

SharePoint 2013/IIS 7.5 模拟/委派/双跳

android - 使用 Firebase 身份验证时 token 服务 API 中的错误请求