kotlin 基础 语言特性
kotlin 基础入门
第三章 kotlin 语言特性
文章目录
- kotlin 基础入门
- 前言
前言
任何语言都有自己的特性,了解特性,才能深入的学习
1、可空性特点
// kotlin 在声明参数的时候,默认是不可空类型。 var name: String = "tiger"// name = null 如果赋值为null 将会报错, 可以赋值成 空串 "" println(name) // 但是我们在声明时,使用 ? 指定成可空类型 var name2: String ? name2 = null name2 = "tiger" println(name2)
2、安全调用操作符
var name: String ? name = "tiger" name = null// name 是可空类型,可能是null 想要使用name,必须给出补救措施,在name后面添加 ? 符号// name 是可空类型 如果真的是null,?后面的代码不执行,就不会引发空指针异常 val str = name?.capitalize() println(str)
3、使用带let 的安全调用
var name: String? = null name = "tiger" name = ""// name 是可空类型,可能是null 想要使用name,必须给出补救措施,在name后面添加 ? 符号// name 是可空类型 如果真的是null,?后面的代码不执行,就不会引发空指针异常 val str = name?.let {//如果能进入这里,it 一定不为nullif (it.isBlank()){ // isBlank name是空串 "" 没有内容 "Default"}else{ "我是:$it"} } println(str)
4、非空断言操作符
var name: String? = null// name 是可空类型,可能是null 想要使用name,必须给出补救措施,在name后面添加 ? 符号 name = "tiger"// !! 断言操作符,和Java一样,不论name 是否为空,都会走后面的代码// 如果不能保证name 被赋值,就会出现崩溃的情况 val str = name!!.capitalize() println(str)
5、对比 if 判断null 值情况
var name: String? = null// name 是可空类型,可能是null 想要使用name,必须给出补救措施,在name后面添加 ? 符号 if (name != null){ // if 也算是补救措施,代码会自动识别, 和Java一样 val str = name.capitalize() println(str) }else{ println("name is null") }
6、空合并操作符
var name: String? = "tiger" name = null // ?: 空合并操作符, 如果name 等于 null ,就会执行 ?: 后面的区域 println(name ?: "原来你没名字啊") // let 函数 + 空合并操作符 println(name?.let { "$it" ?: "原来你没名字啊" })
7、异常处理与自定义异常
try { var name: String? = null checkException(name) println(name!!.capitalize()) }catch (e: Exception){ println("啊呀,又出差了 $e") }fun checkException(name: String?) { name ?: throw CustomException()}// 自定义的异常class CustomException : IllegalArgumentException("传null 还想使用 非空断言操作符?不出错才怪呢")
8、substring
val info = "You are handsome." val indexOf = info.indexOf(".") println(info.substring(0, indexOf))// kotlin 基本使用下面的这种方式截取, 从0 直到(until) indexOf println(info.substring(0 until indexOf))
9、sqlit 操作 (分割操作)
val jsonText = "张三,王五,大漂亮,杨美丽"// list 自动类型推断成 list == List val list = jsonText.split(",")// 直接输出list 集合 println(list)// C++ 里面有解构操作。 kotlin 里面也有解构操作 val (v1, v2, v3, v4) = list println("解构之后的4个数据,分别是: v1:$v1, v2: $v2, v3: $v3, v4: $v4")
10、replace 完成加密解码操作
val sourcePwd = "qwertyuiopasdfghjklzxcvbnm" println(sourcePwd)// 加密操作:就是把字符替换打乱的操作 val newPwd = sourcePwd.replace(Regex("[asdwq]")){ when(it.value){// 轮询字符串中的每个字符 "a" -> "2" "s" -> "4" "d" -> "3" "w" -> "5" "q" -> "7" else -> it.value //不做任何操作,直接返回原值 } } println(newPwd)// 解密操作 val sourcePwdNew = newPwd.replace(Regex("[24357]")){ when(it.value){ "2" -> "a" "4" -> "s" "3" -> "d" "5" -> "w" "7" -> "q" else -> it.value } } println(sourcePwdNew)
11、== 与 === 比较操作符
// == 是内容的比较,相当于Java 中的 equals()// === 是引用的比较,对比的是状态池里面的引用 val name1 = "Tiger" val name2 = "tiger" val name3 = "tiger" val name4 = name2.capitalize() println(name1 === name2) println(name3 == name2) println(name1 === name4)
12、字符串的遍历
val str = "qwertyuiopasdfghjklzxcvbnm" str.forEach {// it 隐式函数,是str 中的每一个字符 println("遍历出来的数据 $it") }
13、数字类型的安全转换函数
val number: Int = "666".toInt() println(number) val number1: Int = "666.6".toInt() // 字符串里面放入double 类型,转换成int 类型,会失败导致程序崩溃 println(number1) // 解决 上面崩溃的问题 val number2: Int? = "666.6".toIntOrNull() println(number1 ?: "字符类型转换失败,返回一个null ")
14、Double 转 Int 类型格式化
// 四舍五入 算法转int println(54.2334.toInt())// 四舍五入 算法转int println(54.2334.roundToInt())// 保留小数点后三位 val r = "%.3f".format(53.3432212) println(r)
15、apply 内置函数
val info = "The tiger you are the most handsome"// 普通写法 println("info 字符串的长度是 ${info.length}") println("info 的最后一个字符是 ${info[info.length-1]}") println("info 全部转换成大写字符 ${info.toUpperCase()}")// apply 内置函数的方式// info.apply 的特点:apply 函数始终是返回 info 本身 String 类型 val str = info.apply {// 大部分情况下,匿名函数,都会持有一个it ,但是apply 不会持有it,却会持有当前 this == info 本身println("info 字符串的长度是 ${this.length}")println("info 的最后一个字符是 ${info[this.length-1]}")println("info 全部转换成大写字符 ${this.toUpperCase()}")//也可以直接把this 去掉println("info 字符串的长度是 ${length}")println("info 的最后一个字符是 ${info[length-1]}")println("info 全部转换成大写字符 ${toUpperCase()}") } println(str)// 真正使用apply 函数的方法如下// info.apply 特点: apply 函数始终是返回 info 本身,可以使用链式调用 info.apply { println("info 字符串的长度是 ${length}") }.apply { println("info 的最后一个字符是 ${info[length-1]}") }.apply { println("info 全部转换成大写字符 ${toUpperCase()}") }// 文件读取小例子// 普通写法 val file = File("/Users/tiger/Desktop/aaa.text") file.setExecutable(true) file.setReadable(true) println(file.readLines())// apply 写法 val r = file.apply { setExecutable(true) }.apply { setReadable(true) }.apply { println(file.readLines()) }
16、let 内置函数
// 普通方式,对集合 中的第一个数据进行相加 val list = listOf(4, 3, 43, 345, 2) val value1 = list.first() val result = value1 + value1 println("普通方式 集合第一个数字相加和 $result")// let 方式,对集合 中的第一个数据进行相加 val result2 = list.let {//隐式函数 it == list 集合本身 it.first() + it.first() // 匿名函数的最后一行,作为返回值,确定返回值类型 } println(result2) println(getMethod("tiger")) println(getMethod2("tiger"))// 普通方式 对值判断null 并返回fun getMethod(value: String?): String { return if (value == null) "你传递的内容是个null" else "你传递了一个数据过来,我还给你 $value"}// let方式 + 空合并操作符 对值判断null 并返回fun getMethod2(value: String? ) : String { return value?.let { "你传递了一个数据过来,我还给你 $it" } ?: "你给了一个null ,还想让我返回?"}
17、run 内置函数
val str = "tiger is Ok" str.run {// run 匿名函数和 apply 一样,它们都有一个 this == str 本的函数 println("输入的字符串是: $this") } /** * 使用run 写一个小例子 * 1、具名函数判断字符串的长度, * 2、具名函数判断长度是否合格 * 3、具名函数 获得合格参数 * 4、打印输出 */ str.run(::isLong) .run(::showText) .run(::resultText) .run(::println)// 再来一个匿名函数的例子 str.run { length > 5 } .run { if (this) "你输入的字符串合格了" else "你输入的字符串不合格" } .run { "我终于走到了这里 $this" } .run { println(this) }// 具名函数 字符串长度 验证fun isLong(str: String): Boolean { return str.length > 5}// 验证长度是否合格fun showText(isLong: Boolean): String { return if (isLong) "你输入的字符串合格了" else "你输入的字符串不合格"}// 获取字符串验证之后的结果fun resultText(showText: String): String { return "我终于走到了这里 $showText"}
18、with 内置函数
val str = "tiger is ok"// 具名函数 val w1 = with(str, ::getLength) val w2 = with(w1, ::getInfo) with(w2, ::logInfo)// 匿名函数// with 和 apply run 函数一样,持有的也是this 本身 with( with(with(str){length }){"字符串的长度是2 $this" }){println(this) }// 获取字符串的长度fun getLength(str: String) = str.length// 读取上面函数的值fun getInfo(len: Int) = "字符串的长度是 $len"// 打印输出结果fun logInfo(infoMap: String) = println(infoMap)
19、also 内置函数
// also 的返回类型,和 apply 一样,返回数据的类型,取决于传入的数据类型// also 持有的是一个it, 这里和let 一样 val str = "tiger is ok" str.also { println(it.length) }.also { println(it.first()) }.also { println(it.capitalize()) }.also { println("终于结束了") }
20、takeIf 内置函数
println(checkPermissionSystem("tiger", "123456"))// takeIf + 空安全合并fun checkPermissionSystem(name: String, pwd: String): String { return name.takeIf { permissionSystem(name, pwd) } ?: "权限不够"}// 权限判断private fun permissionSystem(userName: String, userPwd: String): Boolean { return userName == "tiger" && userPwd == "123456"}
21、takeUnless 内置函数
takeIf 和 takeUnless 功能是相反的
name.takeIf { true/false } true返回的是name,false 返回的是null
name.takeUnless { true/ false } true 返回的是null ,false 返回是name
为什么有takeUnless 的出现,一个takeIf 不就可以了吗?请看下面的代码
val manager = Manager(); manager.setInfoValue("tiger")// takeUnless.isNullOrBlank() 一起使用,可以验证字符串有没有经过初始化 val result = manager.getInfoValue().takeUnless { it.isNullOrBlank() } ?: "你的数据没有初始化,还是个null" println(result)class Manager { private var infoValue: String? = null fun getInfoValue() = infoValue fun setInfoValue(infoValue: String) { this.infoValue = infoValue }}