伴侣对象块和kotlin类外的趣味之间的区别?
我正在学习kotlin,最近发现了写kotlin的一个有趣的方式,但是不能真正理解它。
采取了我从这里学习的代码
fun drawerImageLoader(actions: DrawerImageLoaderKt.() -> Unit): DrawerImageLoader.IDrawerImageLoader { val loaderImpl = DrawerImageLoaderKt().apply(actions).build() DrawerImageLoader.init(loaderImpl) return loaderImpl } class DrawerImageLoaderKt { ... }
为什么要在类的外面定义drawerImageLoader
? 为什么不能在class级和companion object
块内?
另外,在DrawerImageLoaderKt.()
中.()
是什么意思?
该函数在类的外部定义,为DrawerImageLoader.IDrawerImageLoader
对象提供某种工厂,所以它不绑定到具体的实例。
DrawerImageLoaderKt.()
语法定义了一个带有Receiver的Lambda ,我在这个线程中描述了: 如何创建像anko这样的嵌套函数回调 – DSL语法Kotlin
带有Receiver的Lambda使我们能够在函数文本的接收方(这里是DrawerImageLoaderKt
)上调用方法,而不需要任何特定的限定符(这就是drawerImageLoader
的调用方所要做的)。 这与扩展函数非常相似,也可以在扩展中访问接收者对象的成员。
噢,这是我的图书馆:)
drawerImageLoader
函数被定义为一个包级别的函数,这样它就可以被调用,而不用加前缀(如果它是一个实例或者object
方法,你必须这样做)。 当你调用它的时候,这给你下面的语法(参见这里的代码):
override fun onCreate() { super.onCreate() drawerImageLoader { set { ... } cancel { ... } } }
如果它是在一个普通的或伴随的对象,它会看起来像这样,而我相信使一个不太好的DSL:
override fun onCreate() { super.onCreate() SomeClass.drawerImageLoader { set { ... } cancel { ... } } }
至于其参数的types,@ s1m0nw1已经大部分回答了这个部分,但是我会多添加一些。
这是一个带有接收器的lambdaexpression式,它将您DrawerBuilderKt
在传递给drawerImageLoader
函数的lambdaexpression式中的DrawerBuilderKt
范围内。 由于这个类有set
, cancel
和placeholder
方法,所以可以在lambda里面使用。