功能接收器和扩展功能的区别
我正在读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
上课本身。