首页 文章

功能接收器和扩展功能之间的区别

提问于
浏览
3

我正在阅读有关Kotlin的内容,并没有完全理解

从我理解的扩展函数赋予具有新功能的类的能力,而不必从类继承

什么是接收器相同,除了它可以分配给变量

还有别的吗?

有人可以提供一些例子

1 回答

  • 6

    扩展功能:

    与Swift和C#一样,Kotlin提供了使用新功能扩展类的功能,而无需修改类或从类继承 .

    你可能想知道为什么?因为我们无法编辑和添加函数到语言或SDK类 . 所以我们最终用Java创建Util类 . 我相信所有项目都有一堆* Utils类来放置在代码库中多个位置使用的辅助方法 . 扩展函数有助于解决此Util问题 .

    我们如何在Java中编写一个辅助方法来查找给定的长值是否指向今天?

    public class DateUtils {
    
        public static boolean isToday(long when) {
            // logic ...
        }
    }
    

    我们通过将long值作为参数传递来调用该方法:

    void someFunc(long when) {
        boolean isToday = DateUtils.isToday(when);
    }
    

    在Kotlin中,我们可以扩展Long类以在其中包含isToday()函数 . 我们可以像在类中的任何其他成员函数一样在Long值上调用isToday()函数 .

    // Extension function
    fun Long.isToday(): Boolean {
        // logic ... 
    }
    
    fun someFunc(time: Long) {
        val isToday = time.isToday()
    }
    

    与Util方法相比,Kotlin使用Extension函数提供了更丰富的语法 .

    这提高了代码的可读性,从而提高了其可维护性 . 我们从IDE的代码完成中获得了一些帮助 . 因此,我们不必记住要用于所需功能的Util类 .

    在引擎盖下,Kotlin编译器生成静态助手方法,就像我们将它们编写为Java静态Util方法一样 . 因此,我们在Kotlin中获得了这种更好,更丰富的语法而不牺牲任何性能 .

    与函数类似,Kotlin还支持扩展属性,我们可以在现有类中添加属性 .

    高阶函数:

    高阶函数是将函数作为参数或返回函数的函数 .

    让我们看看如何编写更高阶函数 .

    fun execute(x: Int, y: Int, op: (Int, Int) -> Int): Int {
        return op(x, y)
    }
    

    这里第三个参数(op)是一个函数,因此它使该函数成为一个更高阶函数 . 参数op的类型是一个函数,它将2个Int作为参数并返回一个Int .

    要调用此高阶函数,我们可以传递函数或lambda表达式:

    execute(5, 5) { a, b -> a + b }
    

    Receiver(或带有Receiver或带有Recevier的Lambda的函数文字):

    以扩展函数作为参数的高阶函数称为Lambda with Receiver .

    让我们看一下Kotlin标准库中提供的apply函数的实现 .

    inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
    

    我们传递给这个apply函数的函数实际上是类型T的扩展函数 . 所以在lambda函数中,我们可以访问类型T的属性和函数,就像我们在类T本身内编写这个函数一样 .

    这里泛型类型T是接收器,我们传递lambda函数,因此名称Lambda与Receiver .

    另一个例子:

    inline fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {
        beginTransaction()
        try {
            func()
            setTransactionSuccessful()
        } finally {
            endTransaction()
        }
    }
    

    这里,inTransaction()是SQLiteDatabase类的Extension函数,inTransaction()函数的参数也是SQLiteDatabase类的扩展函数 . 这里SQLiteDatabase是接收器,用于作为参数传递的lambda .

    要调用该函数:

    db.inTransaction {
        delete( ... )
    }
    

    这里的delete()是 SQLiteDatabase 类的函数,因为我们传递的lambda是接收器 SQLiteDatabase 的扩展函数,我们可以访问delete函数而不需要任何附加的限定符,就像我们从 SQLiteDatabase 内部调用函数一样阶级本身 .

相关问题