我正在读关于Kotlin的内容并没有完全理解
从我理解的扩展函数赋予具有新功能的类的能力,而不必从类继承
什么是接收器相同,除了它可以分配给变量
还有别的吗?
有人可以提供一些例子
与Swift和C#一样,Kotlin提供了使用新功能扩展类的功能,而无需修改类或继承类.
你可能想知道为什么?因为我们无法编辑和添加函数到语言或SDK类.所以我们最终用Java创建Util类.我相信所有项目都有一堆*Utils类来放置在代码库中多个位置使用的辅助方法.扩展函数有助于解决此Util问题.
我们如何在Java中编写一个辅助方法来查找给定的long值是否指向今天?
public class DateUtils {
public static boolean isToday(long when) {
// logic ...
}
}
Run Code Online (Sandbox Code Playgroud)
我们通过将long值作为参数传递来调用该方法:
void someFunc(long when) {
boolean isToday = DateUtils.isToday(when);
}
Run Code Online (Sandbox Code Playgroud)
在Kotlin中,我们可以扩展Long类以在其中包含isToday()函数.我们可以像在类中的任何其他成员函数一样调用Long值本身的isToday()函数.
// Extension function
fun Long.isToday(): Boolean {
// logic ...
}
fun someFunc(time: Long) {
val isToday = time.isToday()
}
Run Code Online (Sandbox Code Playgroud)
与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)
}
Run Code Online (Sandbox Code Playgroud)
这里第三个参数(op)是一个函数,因此它使该函数成为一个更高阶函数.参数op的类型是一个函数,它将2个Int作为参数并返回一个Int.
要调用此高阶函数,我们可以传递函数或lambda表达式:
execute(5, 5) { a, b -> a + b }
Run Code Online (Sandbox Code Playgroud)
以扩展函数作为参数的高阶函数称为Lambda with Receiver.
让我们看一下Kotlin标准库中提供的apply函数的实现.
inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
Run Code Online (Sandbox Code Playgroud)
我们传递给这个apply函数的函数实际上是类型T的扩展函数.所以在lambda函数中,我们可以访问类型T的属性和函数,就好像我们在类T本身内编写这个函数一样.
这里泛型类型T是接收器,我们传递一个lambda函数,因此名称为Lambda和Receiver.
另一个例子:
inline fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {
beginTransaction()
try {
func()
setTransactionSuccessful()
} finally {
endTransaction()
}
}
Run Code Online (Sandbox Code Playgroud)
这里,inTransaction()是SQLiteDatabase类的Extension函数,inTransaction()函数的参数也是SQLiteDatabase类的扩展函数.这里SQLiteDatabase是接收器,用于作为参数传递的lambda.
要调用该函数:
db.inTransaction {
delete( ... )
}
Run Code Online (Sandbox Code Playgroud)
这里的delete()是SQLiteDatabase类的函数,因为我们传递的lambda是接收器的Extension函数,SQLiteDatabase我们可以访问delete函数而不需要任何额外的限定符,就像我们从SQLiteDatabase类本身内部调用函数一样.
虽然@Bob 的回答对 Kotlin 的信息比我希望的要多得多,包括扩展函数,但它并没有直接提到https://kotlinlang.org/docs/ 中描述的“函数文字与接收器”之间的比较reference/lambdas.html#function-literals-with-receiver和扩展函数 ( https://kotlinlang.org/docs/reference/extensions.html )。即之间的区别:
val isEven: Int.() -> Boolean = { this % 2 == 0 }
Run Code Online (Sandbox Code Playgroud)
和
fun Int.isEven(): Boolean = this % 2 == 0
Run Code Online (Sandbox Code Playgroud)
名称的接收者部分是指接收基本Int参数的这两种语法为this。
据我了解,两者之间的区别仅在于一个是确认函数类型的表达式,另一个是声明。从功能上讲,它们是等效的,并且都可以称为:
when { myNumber.isEven() -> doSomething(myNumber) }
Run Code Online (Sandbox Code Playgroud)
但是一个用于扩展库,而另一个通常用作具有函数类型参数的函数的参数,特别是 Kotlin builder DSL。
| 归档时间: |
|
| 查看次数: |
842 次 |
| 最近记录: |