如何有效阅读/解释此Kotlin代码?

时间:2019-02-01 15:23:33

标签: kotlin

我知道如何阅读/解释Java代码,并且可以编写它。但是对于kotlin来说,我是新手,我发现下面的代码很难阅读。也许我缺少该语言的关键概念。

但是,您将如何解释此代码?为了快速有效地理解这段代码,您打算从哪里开始阅读它?左到右?右到左?首先分解参数?看看返回值吗?

inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

3 个答案:

答案 0 :(得分:4)

因此,就像Java一样,这是一个通用函数。它有两个类型参数T,它们的类型分别为“ Any”(Java中的“ Any”类似于“ Object”)和R。输入参数是可为空的T,如问号所示。可空类型表示该值可以为空。另一个函数参数是一个接受T(不可为null的类型)并返回R的函数。该函数的返回类型为可为null的R。该函数的主体表示,如果input不为null,则将其调用并将其传递给回调并返回该值。如果input为null,则返回null。

答案 1 :(得分:3)

让我们逐一剖析函数定义:

inline:表示该函数的代码将直接复制到调用站点,而不是像普通函数一样被调用。

fun:我们正在定义一个函数。

<T : Any, R>:此函数采用两个通用类型参数,TRT类型仅限于Any类型(这是Kotlin的Object类型)。这似乎是多余的,但实际上是说T不能是可为空的类型(Any?)。

ifNotNull:函数的名称。

input: T?:类型T?的第一个参数。我们可以在此处将?放在T类型上,因为我们在类型声明中将其限制为非空类型。

callback: (T) -> R:第二个参数的类型为(T) -> R,它是一种函数类型。这是一种函数类型,它以T作为输入并返回R

: R?:该函数返回类型为R或null的值。

return input?.let(callback):函数体。 let函数接受一个函数参数,并用其接收者(input)对其进行调用,然后返回该函数的结果。 ?之后的inputlet仅当input不为空时才被调用。如果input为null,则表达式将返回null。

该函数等效于此Java方法(内联和可为空的类型除外):

public <T, R> R ifNotNull(final T input, final Function<T, R> callback) {
    if (input == null) {
        return null;
    }

    return callback.apply(input);
}

答案 2 :(得分:2)

Matt的答案可以一口气解释一切。我会尝试看看如何您可能会去阅读这样的代码。

现在跳过第一个单词,最重要的是第二个单词:fun。因此,整个过程都在定义一个函数。告诉您其余的期望。

花括号告诉您这是一个块函数,而不是单行代码,因此您期望的基本结构为:fun name(params): returnType { code }。其余的填补了空白! (这符合Kotlin声明的一般模式,该类型在冒号之后排在第二位.Java的对应词当然更像returnType name(params) { code }。)

与Java一样,尖括号中的内容提供了通用参数,因此我们现在可以略过,直接进入下一个最重要的位,即所定义函数的名称ifNotNull

通过这些,我们可以阅读其余内容。 inline是一个简单的修饰符,告诉您该函数将由编译器内联。 (这可以启用某些功能,并限制其他功能,但我现在不必担心。)

<T : Any, R>给出函数使用的通用参数类型。第一个是T,它必须是Any或子类型;第二个是R,不受限制。

({Any类似于Java的Object,但不能为null;最上面的类型是相关的Any?,它也允许null。因此,除了可空性外,它等效于Java <T extends Object, R>。)

继续,我们在括号中包含功能参数。同样,有两个:第一个称为input,类型为T?,这意味着它可以接受任何类型的T值,也可以接受null。第二个参数称为callback,类型更复杂,为(T) -> R:它是一个以T作为参数并返回R的函数。 (Java没有这样的函数类型,因此可能看起来最奇怪.Java最接近的等效项是Function<R, T>。)

括号后是该函数本身的返回类型 R?,这意味着它可以返回Rnull

最后,括号中是该函数的实际 code 。该行只有一行,它返回表达式的值。 (其作用是检查input的值是否为null:如果是,它将直接返回null。否则,它将调用参数中给定的callback函数,将input作为参数传递,并返回其结果。)

尽管这是一个简短的声明,但它非常抽象并且包含很多内容,因此也难怪您会发现很难! (格式类似于Java方法声明-但Kotlin的表达能力很强,因此等效代码往往比Java短一些。而泛型使其变得更加复杂。)如果您刚开始学习Kotlin,我就是d建议一些简单的方法:-)

(好消息是,就像在Java中一样,您通常不需要阅读stdlib代码。尽管Kotlin的文档注释很少达到Java的示例性水平,但通常仍然足够。)