Kotlin基础知识_09-高阶函数的应用
Kotlin基础知识_09-高阶函数的应用 vararg&Any
1. 简化 SharedPreferences API
日常写法:
val sp = getSharedPreferences("data", MODE_PRIVATE)
val editor = sp.edit()
editor.putBoolean("is_switch", true)
editor.putInt("last_value", 20)
editor.putFloat("stu_grade", 20.5f)
editor.apply()
使用高阶函数简化:
首先为SharedPreferences
定义一个扩展函数:
fun SharedPreferences.save(block: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.block()
editor.apply()
}
调用:
getSharedPreferences("data", MODE_PRIVATE).save {
putBoolean("is_switch", true)
putInt("last_value", 20)
putFloat("stu_grade", 20.5f)
}
直接使用Android core-ktx的lib
Google 已为 SharedPreferences
类提供了类似的扩展函数,包含在下面的lib中:
SharedPreferences.kt
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.core.content
import android.annotation.SuppressLint
import android.content.SharedPreferences
/**
* Allows editing of this preference instance with a call to [apply][SharedPreferences.Editor.apply]
* or [commit][SharedPreferences.Editor.commit] to persist the changes.
* Default behaviour is [apply][SharedPreferences.Editor.apply].
* ```
* prefs.edit {
* putString("key", value)
* }
* ```
* To [commit][SharedPreferences.Editor.commit] changes:
* ```
* prefs.edit(commit = true) {
* putString("key", value)
* }
* ```
*/
@SuppressLint("ApplySharedPref")
public inline fun SharedPreferences.edit(
commit: Boolean = false,
action: SharedPreferences.Editor.() -> Unit
) {
val editor = edit()
action(editor)
if (commit) {
editor.commit()
} else {
editor.apply()
}
}
所以可以直接以下面的方式去调用,效果是一样的:
getSharedPreferences("data", MODE_PRIVATE).edit {
putBoolean("is_switch", true)
putInt("last_value", 20)
putFloat("stu_grade", 20.5f)
}
2. 简化 ContentValues API
日常写法
val contentValues = ContentValues()
contentValues.put("name", "ana")
contentValues.put("age", "20")
contentValues.put("sex", "boy")
contentValues.put("address", "beijing")
定义一个函数简化
fun buildContentValues(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
}
val values = buildContentValues("name" to "ana", "age" to 20, "sex" to "boy", "address" to "beijing")
使用高阶函数继续简化
fun buildContentValues(vararg pairs: Pair<String, Any?>): ContentValues =
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)
}
}
}
直接使用Android core-ktx的lib
Google 已为 ContentValues
类提供了类似的封装函数,同样也包含在 androidx.core:core-ktx
lib中,名为:contentValuesOf
:
val values = contentValuesOf("name" to "ana", "age" to 20, "sex" to "boy", "address" to "beijing")
ContentValues.kt
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.core.content
import android.content.ContentValues
/**
* Returns a new [ContentValues] with the given key/value pairs as elements.
*
* @throws IllegalArgumentException When a value is not a supported type of [ContentValues].
*/
public fun contentValuesOf(
vararg pairs: Pair<String, Any?>
): ContentValues = ContentValues(pairs.size).apply {
for ((key, value) in pairs) {
when (value) {
null -> putNull(key)
is String -> put(key, value)
is Int -> put(key, value)
is Long -> put(key, value)
is Boolean -> put(key, value)
is Float -> put(key, value)
is Double -> put(key, value)
is ByteArray -> put(key, value)
is Byte -> put(key, value)
is Short -> put(key, value)
else -> {
val valueType = value.javaClass.canonicalName
throw IllegalArgumentException("Illegal value type $valueType for key \"$key\"")
}
}
}
}
Note:
vararg
是kotlin中的关键字,用于表示可变参数;Any
是kotlin中的关键字,代表所有类型的基类,类似于java中的Object
类;"name" to "ana"
这种写法会自动转换为Pair 键值对。