Kotlin扩展功能与成员功能?

时间:2017-11-08 13:55:19

标签: kotlin kotlin-extension

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

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

class Foo { ... }

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

与成员函数相反:

class Foo {

    ...

    fun bar() {
        // Some stuff
    }
}

是否有推荐的做法?

4 个答案:

答案 0 :(得分:7)

何时使用成员函数

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

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

何时使用扩展功能

如果符合以下任何条件,则应使用扩展功能:

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

为什么?

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

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

答案 1 :(得分:6)

从我的观点来看,使用扩展功能有两个令人信服的理由:

  1. To"延伸"你不是作者/不能改变的类的行为(以及继承没有意义或不可能的地方)。

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

  3. 听起来#1在你的情况下并不是一个问题,所以它真的更像是#2。

答案 2 :(得分:0)

扩展功能类似于您作为实用程序功能创建的功能。

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

DiskSpaceAvailable

这段代码可以像Java一样用Java编写实用函数:

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

所以它本质上是这样做的,用你调用的对象调用相同的函数将作为第一个参数传递给参数。就像我在class StringUtils { public static boolean isEmail(String email) { // check for email pattern and return true/false } } 中给出的相同功能一样。

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

java

根据文档,

  

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

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

何时创建扩展功能?

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

使用扩展功能的另一个原因是,您不必扩展该类以使用这些方法,就好像它们属于该类(但实际上不属于该类)。

希望它对你有所帮助..

答案 3 :(得分:0)

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

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