【思货】kotlin协程优雅的与Retrofit缠绵-kotlin DSL简述

这是一篇辅助文章,为了辅助你们理解后面的文章,先前先简单的阐述下kotlin的DSL。java

DSL是什么

DSL指的是特定领域语言,利用kotlin的DSL语言,咱们能够写成更加整洁的代码,是代码的可阅读行大幅度提高。基本的概念以及好处我就再也不重复阐述了,网上已经有不少相似的文章了,我就经过具体的代码示例进行展现好了。bash

kotlin DSL代码长什么样

EditText

我仍是从最多见EditTextTextWatcher提及。app

Java中当咱们须要添加文本输入监听的的时候,是以下的写法:ide

editText.addTextChangedListener(new TextWatcher() {
	@Override
  public void beforeTextChanged(CharSequence s, int start, int count, int after) {

  }

  @Override
  public void onTextChanged(CharSequence s, int start, int before, int count) {

  }

  @Override
  public void afterTextChanged(Editable s) {

  }
});
复制代码

可是每每有时,咱们只须要afterTextChanged监听,并不须要其余两个,但因为接口的限制,咱们不得不所有写出将其实现。致使书写体验和阅读体验降低。性能

那么在kotlin中咱们能够骚操做:学习

editText.onTextChange {
	afterTextChanged { s ->

	}
}
复制代码

确定有小伙伴,是这个表情:ui

https://user-gold-cdn.xitu.io/2019/6/8/16b3554d466d9837?w=360&h=360&f=jpeg&s=13317

那么这是如何实现的呢,首先,自定义个类,继承TextWatcherspa

class TextWatcherDsl : TextWatcher {
    private var afterTextChanged: ((s: Editable?) -> Unit)? = null
    private var beforeTextChanged: ((s: CharSequence?, start: Int, count: Int, after: Int) -> Unit)? =
        null
    private var onTextChanged: ((s: CharSequence?, start: Int, before: Int, count: Int) -> Unit)? =
        null

    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)
    }

    fun afterTextChanged(after: (s: Editable?) -> Unit) {
        afterTextChanged = after
    }

    fun beforeTextChanged(before: (s: CharSequence?, start: Int, count: Int, after: Int) -> Unit) {
        beforeTextChanged = before
    }

    fun onTextChanged(onChanged: (s: CharSequence?, start: Int, before: Int, count: Int) -> Unit) {
        onTextChanged = onChanged
    }
}

复制代码

这里面涉及到kotlin的参数方法内容(即:方法能够直接做为参数传递进),不懂自行百度,再也不讲解。code

接下来,来实现一个DSL的扩展方法:orm

inline fun EditText.onTextChange(textWatcher: TextWatcherDsl.() -> Unit): TextWatcher {
    val watcher = TextWatcherDsl().apply(textWatcher)
    addTextChangedListener(watcher)
    return watcher
}
复制代码

ok,搞定了,全部的EditText都具备了onTextChange方法,监听文本的方法须要什么写什么。

  • 一、扩展方法再也不具体解释,不是本文重点

  • 二、这里的inline是指内联方法,即:在编译时期,代码会直接插入掉用处,实际上不是调用外部方法。也就不会形成调用外部方法而致使的性能开销,有兴趣的小伙伴能够百度了学习。

这里须要注意理解下参数TextWatcherDsl.() -> UnitTextWatcherDsl是咱们刚刚自定义的类,而后后面跟了一个,就是说,这个参数能够接收TextWatcherDsl类里的全部方法,只要是它里面的方法均可以传递进来。

SharedPreferences

咱们再来看下Google官方对于SharedPreferences的扩展。惯例,咱们Java中使用SP写入数据是这样的:

SharedPreferences sp = getSharedPreferences("demo", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("key1", "value1");
editor.putString("key2", "value2");
editor.apply();
复制代码

kotlin中是这样的:

val sp = getSharedPreferences("demo", Context.MODE_PRIVATE)
sp.edit {
    putString("key1", "value1")
    putString("key2", "value2")
}
复制代码

是否是简单易读。

https://user-gold-cdn.xitu.io/2019/6/8/16b3554dc9725c58?w=1141&h=640&f=jpeg&s=19829

咱们来看下官方Google是如何实现的这个方法:

inline fun SharedPreferences.edit( commit: Boolean = false, action: SharedPreferences.Editor.() -> Unit
) {
    val editor = edit()
    action(editor)
    if (commit) {
        editor.commit()
    } else {
        editor.apply()
    }
}
复制代码

是的,没错就这么点。

参数SharedPreferences.Editor后面跟了一个,能够接受SharedPreferences.Editor中的方法,例如putString

File

上面的写法,会kotlin的小伙伴应该都见过了。接下来,我来展现下另外一种DSL的写法,可能大家会不多用。

这里我操做File文件的方法来展现。这里我再也不写java代码。

常规写法

首先咱们看一下常规拷贝文件的写法:

fun copyTo(form:File, to: File) {
    // 具体操做文件拷贝的代码
}
复制代码

使用:

copyTo(file1, file2)
复制代码

这种太常见了,Java里也是如此操做的,不细说了。

kotlin扩展写法

接下来改造下,写成扩展方法:

fun File.copyTo(to: File) {
    // 具体操做文件拷贝的代码
}
复制代码

使用:

file1.copyTo(file2)
复制代码

看起来好像舒服了那么一点

终极写法

infix fun File.copyTo(to: File) {
    // 具体操做文件拷贝的代码
}
复制代码

使用:

file1 copyTo file2
复制代码

注意看扩展方法前面多了一个infix来修饰方法,是否是很是接近了咱们人类说话时的语言方式。

大家的表情是这样的:

https://user-gold-cdn.xitu.io/2019/6/8/16b3554dc6182fed?w=301&h=270&f=jpeg&s=7791

相似的方法,在anko库中中也有不少地方使用,多去阅读源码就会发现。

本次的简介就到此为此,但愿经过直接的代码展现,能让各位找到些感受

相关文章
相关标签/搜索