13

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

但是,在代码可读性/结构方面,通过使用扩展函数是否有任何优势:

class Foo { ... }

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

与成员函数相反:

class Foo {

    ...

    fun bar() {
        // Some stuff
    }
}

?

有推荐的做法吗?

4

4 回答 4

17

何时使用成员函数

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

  • 代码最初是用 Kotlin 编写的
  • 你可以修改代码
  • 该方法可以从任何其他代码中使用

何时使用扩展功能

如果以下任何一项适用,您应该使用扩展函数:

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

为什么?

通常,成员函数比扩展函数更容易找到,因为它们保证在它们所属的类(或超类/接口)中。

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

于 2017-11-08T14:01:04.630 回答
12

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

  1. 要“扩展”一个你不是作者/不能改变的类的行为(继承没有意义或不可能)。

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

听起来#1在您的情况下不是问题,因此实际上更多的是#2。

于 2017-11-08T14:01:39.223 回答
3

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

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

// 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
    }
}

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

如果要调用kotlinfrom中创建的扩展函数java,则需要将调用者作为第一个参数传递。像,

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

根据文档,

扩展实际上并不修改它们扩展的类。通过定义扩展,您不会将新成员插入到类中,而只是使新函数可以使用这种类型的变量的点符号调用。

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

何时创建扩展函数?

  • 当您无权访问该课程时。当该类属于您尚未创建的某个库时。
  • 对于原始类型。整数、浮点数、字符串等

使用扩展函数的另一个原因是,您不必为了使用方法而扩展该类,就好像它们属于该类(但实际上不是该类的一部分)。

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

于 2017-11-11T06:55:27.760 回答
0

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

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

于 2021-06-16T11:49:23.117 回答