【问题标题】:How does Kotlin retrieve map values internally with its get functionKotlin 如何使用其 get 函数在内部检索映射值
【发布时间】:2022-12-07 02:03:05
【问题描述】:

在 Kotlin 中,您可以创建这样的地图:

val items = mapOf("a" to 1, "b" to 2)

并检索这样的值:

val item = items["a"]

括号将调用get 函数。查看 Kotlin 的 Maps 源代码,我看到的 get 函数是这样的:

public operator fun get(key: K): V?

我找不到 get 的任何实现,因此不清楚 Kotlin 如何在内部找到地图项。

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    根据您创建 Kotlin 映射的方式,可能会创建不同的实现。但在 mapOf("a" to 1, "b" to 2) 的具体情况下,将创建一个 kotlin.collections.LinkedHashMapLinkedHashMaps 实现取决于目标平台。更多信息可以在这里找到:What does a LinkedHashMap create in Kotlin?。如果目标平台是 JVM,那么底层实现是 java.util.HashMap 并且它是 get 函数。

    【讨论】:

    • 通过 Kotlin 源代码,我注意到它最终会调用特定于平台的函数,通常是 Java 函数。所以我必须查看 Java 实现以了解它是如何完成的。
    【解决方案2】:

    映射类型

    对于大多数 Java 类型,Kotlin 将只使用提供的定义。但对于某些类型,Kotlin 决定对其进行特殊处理,并用自己的版本完全替换 Java 定义。这些类型被称为映射类型.

    可以看到the list of mapped types in the docsMap就是其中之一。

    这意味着 kotlin.collections.Map.get() 没有可见的实现 - 但它将(最终)由实际的 Java Map 实现提供。

    为什么 Kotlin 映射类型?

    为什么这是必要的?一个原因是它提高了空安全性。

    Map.get() 的 Java 实现返回一个不可为 null 的值。

    // Java Map getter - V is not marked as nullable
    public V get(Object key) { ... }
    

    因为 Vplatform type,Kotlin 会认为它是不是为方便起见为空。

    为了避免混淆,Kotlin 的Map.get() 特别将返回值标记为可为空。

    // Kotlin Map getter - V is explicitly marked as nullable
    public operator fun get(key: K): V?
    

    现在,在 Kotlin 中,我们可以安全地从 Maps 中检索值,即使它们丢失了。呸!危机化解。

    也可以看看

    What are nullable rules when calling Java from Kotlin

    【讨论】:

      【解决方案3】:

      运算符[]在各种Map实现中被实现为get,例如参见默认映射here和空映射here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-12
        • 1970-01-01
        • 2020-01-15
        • 2020-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多