Kotlin - 高阶函数的应用

高阶函数非常适用于简化各种API的调用,一些API的原有用法在使用高阶函数简化之后,不管是在易用性还是可读性方面,都可能会有很大的提升。

简化SharedPreferences的用法

之前学的最原始的向SharedPreferences中存储数据的代码如下:

//获取SharedPreferences.Editor对象
val editor = getSharedPreferences("data",Context.MODE_PRIVATE).edit()
editor.putString("name","ZLS") //添加String类型数据
editor.putInt("age",18)
editor.putBoolean("married",false)
editor.apply() //提交数据

但在红色箭头所指的扩展库中,添加了他的简化用法
在这里插入图片描述
它包含了一段类似于下面的代码,可以大大方便SharedPreferences的使用

fun SharedPreferences.edit(block: SharedPreferences.Editor.() -> Unit){
	val editor = edit()
	editor.block()
	editor.apply()
}

通过扩展函数的方式向SharedPreferences类中添加了一个edit函数,并且它还接收一个函数类型的参数,因此edit函数自然就是一个高阶函数了。 由于edit函数内拥有SharedPreferences的上下文,因此这里可以直接调用edit()方法来获取SharedPreferences.Editor对象。另外edit函数接收的是一个SharedPreferences.Editor的函数类型参数,因此这里需要调用editor.block()对函数类型参数进行调用,我们就可以在函数类型参数的具体实现中添加数据了。最后还要调用editor.apply()方法来提交数据,从而完成数据存储操作。
简化后使用代码如下:

getSharedPreferences("data",Context.MODE_PRIVATE).edit{
    putString("name","ZLS")
    putInt("age",18)
    putBoolean("married",false)
}

简化ContentValues的用法

ContentValues主要是用于结合SQLiteDatabase的API存储和修改数据库中的数据,具体的基础用法如 下:

val values = ContentValues()
values.put("name", "Game of Thrones")
values.put("author", "George Martin")
values.put("pages", 720)
values.put("price", 20.85)
db.insert("Book", null, values)

下面介绍通过新建一个方法让其变得简单的用法:
首先新建⼀个ContentValues.kt文件,然后在里面定义一个cvOf()方法:

fun cvOf(vararg pairs: Pair<String, Any?>): ContentValues {
}

这个方法的作用是构建一个ContentValues对象。
首先,cvOf()方法接收了一个Pair参数,也就是使用A to B语法结构创建出来的参数类型,但是在参数前面加上了一个vararg关键字,它对应的就是Java中的可变参数列表,允许向这个方法传入0个、1个、2个甚至任意多个Pair类型的参数,这些参数都会被赋值到使用vararg声明的这一个变量上面,然后使用for-in循环可以将传入的所有参数遍历出来。
再来看声明的Pair类型。由于Pair是一种键值对的数据结构,因此需要通过泛型来指定它的键和值分别对应什么类型的数据。ContentValues的所有键都是字符串类型的,这里可以直接将Pair键的泛型指定成String。但ContentValues的值却可以有多种类型(字符串型、整型、浮点型,甚至是null),所以需要将Pair值的泛型指定成Any?。这是因为Any是Kotlin中所有类的共同基类,相当于Java中的Object,而Any?则表示允许传入空值。

fun cvOf(vararg pairs: Pair<String, Any?>): ContentValues {
	val cv = ContentValues()
 	for (pair in pairs) {
    	val key = pair.first
		val value = pair.second
    	when (value) {
	    	is Int -> cv.put(key, value)
			is Long -> cv.put(key, value)
			is Short -> cv.put(key, value)
			is Float -> cv.put(key, value)
			is Double -> cv.put(key, value)
	 		is Boolean -> cv.put(key, value)
 			is String -> cv.put(key, value)
 			is Byte -> cv.put(key, value)
 			is ByteArray -> cv.put(key, value)
			null -> cv.putNull(key)
    	}
	}
	return cv
}

when语句进入Int条件分支后,这个条件下面的value会被自动转换成Int类型,而不再是Any?类型,这样就不需要像Java中那样再额外进行一次向下转型了, 这个功能在if语句中也同样适用。
有了这个cvOf()方法之后,使用ContentValues时就会变得更加简单了,比如向数据库中插入一条数据就可以这样写:

val values = cvOf("name" to "Game of Thrones", "author" to "George Martin", "pages" to 720, "price" to 20.85)
db.insert("Book", null, values)

此外,还可以借助apply函数进行二次优化

fun cvOf(vararg pairs: Pair<String, Any?>) = ContentValues().apply {
	for (pair in pairs) {
		val key = pair.first
		val value = pair.second
		when (value) {
			is Int -> put(key, value)
			is Long -> put(key, value)
			is Short -> put(key, value)
			is Float -> put(key, value)
			is Double -> put(key, value)
			is Boolean -> put(key, value)
			is String -> put(key, value)
			is Byte -> put(key, value)
			is ByteArray -> put(key, value)
			null -> putNull(key)
		}
	}
}

在上文提到的KTX库中也提供了一个具有同样功能的contentValuesOf()方法,用法如下:

val values = contentValuesOf("name" to "Game of Thrones", "author" to "George Martin", "pages" to 720, "price" to 20.85)
db.insert("Book", null, values)

平时在编写代码的时候,直接使用KTX提供的contentValuesOf()方法就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值