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

我正在读Kotlin,并没有完全明白

从我所了解的扩展功能给予一个具有新功能的类的能力,而不必从类继承

什么是接收者,除了可以分配给变量

还有什么关于它的吗?

有人可以举一些例子

扩展功能:

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

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

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

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

我们通过传递长整型值作为参数来调用这个方法:

 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个Ints为参数并返回一个Int的函数。

为了调用这个高阶函数,我们可以传递一个函数或一个lambda表达式:

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

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

以扩展函数为参数的高阶函数称为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类的扩展函数,inTransaction()函数的参数也是SQLiteDatabase类的扩展函数。 这里SQLiteDatabase是作为参数传递给lambda的接收者。

要调用该函数:

 db.inTransaction { delete( ... ) } 

这里的delete()是SQLiteDatabase类的函数,因为我们传递的lambda函数是接收者SQLiteDatabase的扩展函数,所以我们可以访问delete函数,而没有任何额外的限定符,好像我们正在从SQLiteDatabase上课本身。