Kotlin 扩展函数与成员函数?

Kotlin extension functions vs member functions?

我知道 Kotlin 中使用扩展函数来扩展 class 的功能(例如,来自库或 API 的功能)。

但是,就代码readability/structure而言,使用扩展函数是否有任何优势:

class Foo { ... }

fun Foo.bar() {
    // Some stuff
}

相对于成员函数:

class Foo {

    ...

    fun bar() {
        // Some stuff
    }
}

?

有推荐的做法吗?

何时使用成员函数

如果满足以下所有条件,您应该使用成员函数:

  • 代码最初是用 Kotlin 编写的
  • 您可以修改代码
  • 该方法很有意义,可以从任何其他代码中使用

何时使用扩展功能

如果满足以下任一条件,您应该使用扩展函数:

  • 代码最初是用Java写的,你想添加用Kotlin写的方法
  • 您不能更改原始代码
  • 您想要一个只对代码的特定部分有意义的特殊函数

为什么?

一般来说,成员函数比扩展函数更容易找到,因为它们保证在class它们是(或超级class/interface)的成员中。

它们也不需要导入到所有使用它们的代码中。

在我看来,使用扩展函数有两个令人信服的理由:

  1. "extend" class 的行为你不是 / 的作者不能改变(继承没有意义或不是可能)。

  2. 为特定功能提供范围。例如,扩展函数可以声明为独立函数,在这种情况下它可以在任何地方使用。或者您可以选择将其声明为另一个 class 的(私有)成员函数,在这种情况下,它只能在 class.

  3. 内部使用

听起来 #1 在你的情况下不是问题,所以更多的是 #2。

扩展函数类似于您创建的实用函数。

一个基本的例子是这样的:

// Strings.kt
fun String.isEmail() : Boolean {
    // check for email pattern and return true/false
}

这段代码可以写成 Java 中的效用函数,如下所示:

class StringUtils {
    public static boolean isEmail(String email) {
        // check for email pattern and return true/false
    }
}

所以它本质上做的是,用你调用的对象调用同一个函数将作为第一个参数传递给参数。就像我在 Java 中给出的示例一样。

如果您想从java调用在kotlin中创建的扩展函数,您需要将调用者作为第一个参数传递。喜欢,

StringsKt.isEmail("example@example.com")

根据文档,

Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.

它们只是静态函数,调用者作为第一个参数,其他参数紧随其后。它只是扩展了我们以这种方式编写它的能力。

何时创建扩展函数?

  • 当您无法访问该 class 时。当 class 属于您尚未创建的某个库时。
  • 对于原始类型。 Int、Float、String 等

使用扩展函数的另一个原因是,您不必扩展 class 就可以使用这些方法,就好像它们属于 class (但实际上不是一部分其中 class)。

希望它能让你明白一点..

如其他答案中所述,扩展函数主要用于您无法更改的代码 - 也许您想将围绕某些库对象的复杂表达式更改为更简单、更易读的表达式。

我的做法是为 data classes 使用扩展函数。我的推理纯粹是哲学上的,data classes 应该只用作数据载体,它们不应该携带状态并且它们自己不应该做任何事情。这就是为什么我认为你应该使用扩展函数,以防你需要围绕 data class.

编写函数