DSL 全民公敌

2022-03-24  本文已影响0人  细雨么么

起因:
原文: https://blog.csdn.net/u011133887/article/details/123004000
推送: https://mp.weixin.qq.com/s/TTq709cPl8rMW7ipMF57_g
demo

fun A.extendsf(ry: TextWaterDslImpl.() -> Unit) {
    val tvdslI = TextWaterDslImpl()
    ry.invoke(tvdslI)
    this.addList(tvdslI)
}

fun main() {
    val a=A()
    a.extendsf {
        beforeTv {
            println("开始")
            println(it)
        }

    }
    a.doa1()
}
class TextWaterDslImpl : TvWater {

    private var bTvM1: ((s1: String) -> Unit)? = null
    private var bTvM2: ((s1: String, s2: String) -> Unit)? = null


    fun beforeTv(method: (s1: String) -> Unit) {
        bTvM1 = method
    }

    fun afterTv(method: (s1: String, s2: String) -> Unit) {
        bTvM2 = method
    }

    override fun beforeTv(str: String) {
        bTvM1?.invoke(str)
    }

    override fun afterTv(s1: String, s2: String) {
        bTvM2?.invoke(s1, s2)
    }
}

interface TvWater {

    fun beforeTv(str: String)

    fun afterTv(s1: String, s2: String)

}


class A {

    private var tv: TvWater? = null

    fun addList(tv: TvWater) {
        this.tv = tv
    }

    fun doa1() {
        tv?.beforeTv("xxxdo1")
    }

    fun doa2() {
        tv?.afterTv("xxx01", "xxx02")
    }

}

其中

fun A.extendsf(ry: TextWaterDslImpl.() -> Unit) {
    val tvdslI = TextWaterDslImpl()
    ry.invoke(tvdslI)
    this.addList(tvdslI)
}

中,TextWaterDslImpl.() -> Unit 标明 ry需要的参数类型,他是TextWaterDslImpl中任意的无参且无返回的方法。方法体中执行 ry.invoke(tvdslI) 相当于 tvdsll类设置了你传入的方法,当你调用 doa1()时,执行了rv这个方法,参数回调到 rv 的 方法体中。比较绕。
原文中:

inline fun TextView.addTextChangedListenerClosure(
    crossinline afterTextChanged: (Editable?) -> Unit = {},
    crossinline beforeTextChanged: (CharSequence?, Int, Int, Int) -> Unit = { charSequence, start, count, after -> },
    crossinline onTextChanged: (CharSequence?, Int, Int, Int) -> Unit = { charSequence, start, after, count -> }
) {
    val listener = object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            afterTextChanged.invoke(s)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            beforeTextChanged.invoke(s, start, count, after)
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            onTextChanged.invoke(s, start, before, count)
        }
    }
    this.addTextChangedListener(listener)
}

更好理解一点,其中方法参数,crossinline afterTextChanged: (Editable?) -> Unit = {}, 等于{}是默认空实现,把方法当参数,默认空实现,可以选择重写或者不重写。类似于:


fun main() {
    
    doa1(str2 = "hhh")
}
fun  doa1(str:String="111",str2: String="222"){
    //todo
}

giao 这也太绕了 DSL

上一篇下一篇

猜你喜欢

热点阅读