伴侣对象块中的乐趣和kotlin中的课堂之外的区别?

时间:2017-12-01 20:06:02

标签: kotlin

我学习kotlin并且最近发现了一种写kotlin的有趣方式但却无法理解它。

here

学习代码
fun drawerImageLoader(actions: DrawerImageLoaderKt.() -> Unit): DrawerImageLoader.IDrawerImageLoader {
    val loaderImpl = DrawerImageLoaderKt().apply(actions).build()
    DrawerImageLoader.init(loaderImpl)
    return loaderImpl
}

class DrawerImageLoaderKt {
    ...
}

为什么drawerImageLoader在课外定义?为什么不能在班级内companion object区内?

此外,.()DrawerImageLoaderKt.()中的含义是什么?

2 个答案:

答案 0 :(得分:4)

该函数在类外定义,为DrawerImageLoader.IDrawerImageLoader对象提供某种工厂,因此它不受具体实例的约束。

语法DrawerImageLoaderKt.()定义了Lambda with Receiver,我在此帖子中描述了How to create nested function callbacks like anko - DSL syntax Kotlin

带有Receiver的 Lambda 使我们能够在其正文中的函数文字的接收者(此处为:DrawerImageLoaderKt)上调用方法,而不需要任何特定限定符(这就是{{{}的调用者1}}会做)。这与扩展函数非常相似,在扩展函数中也可以访问扩展中的接收者对象的成员。

答案 1 :(得分:4)

哦,嘿,这是我的图书馆:)

drawerImageLoader函数被定义为包级别函数,因此可以在不加前缀的情况下调用它(如果它是实例或object方法,则必须这样做)。当您调用它时,它会为您提供以下语法(请参阅代码here):

override fun onCreate() {
    super.onCreate()

    drawerImageLoader {
        set {
            ...
        }
        cancel {
            ...
        }
    }
}

如果它是普通或伴侣对象,它会看起来像这样,我相信这会让一个不太好的DSL:

override fun onCreate() {
    super.onCreate()

    SomeClass.drawerImageLoader {
        set {
            ...
        }
        cancel {
            ...
        }
    }
}

至于其参数的类型,@ s1m0nw1已经主要回答了那个部分here,但是我只会添加一些。

它是一个带接收器的lambda,它将你置于lambda内DrawerBuilderKt的范围内,你将传递给drawerImageLoader函数。由于此类具有setcancelplaceholder方法,因此可以在lambda中使用这些方法。