1.空安全和异常
// ? 使用在类型后面就是此类型可null
// ?. 使用在对象后面表示此对象非null才会执行后面的
// !!. 使用在对象后面表示此对象肯定不为null,如果为空会直接崩掉
// ?: 空合并,类似于三木运算符 val hisname = it ?: "李四"
//name ?:throw myException() 抛出异常,?:右边没有返回值,原因是,抛
//异常就是打断,已经不需要遵守返回值的规则
//先决条件函数,就是内置的一些函数,checkNotNull() error()
2.字符串
val name = "kiujkkjh"
val names = "张三,李四,王五"
val newName = name.substring(0 until name.indexOf("j"))//substring 字符串的截取
val nameList = names.split(",") // split 字符串转为集合
//可以直接使用split给多个变量赋值(list支持解构语法)
val (user1:String,user2:String,user3:String) = names.split(",")
//replace 字符串的替换
val str1 = "the people's republic of china"
val str2 = str1.replace(Regex("aeiou")){
when (it.value){
"a" -> "2"
"e" -> "6"
"i" -> "3"
"o" -> "9"
"u" -> "7"
else -> it.value
}
}
// 遍历字符串
str1.forEach{
println("fule-- $it")
}
}
标准库函数
-apply,-let,-run,-with,-also,-takeif,-takeUnless
// apply返回的是接受者对象(name1)
/*调用一个函数类配置接受者时,变量名就省掉了(即user.name中。user省掉了),这是因为,在lambda表达式里,
apply能让每个配置函数都作用于接受者,这种行为有时又叫做相关作用域,因为
lambda表达式里的所有函数调用都是针对接受者的,或者说,它们是针对接受者的隐式调用*/
val name1 = user?.apply {
name = "zhangsan"
age = 15
}
//let会返回lambda的最后一行
/*let函数能使某个变量作用于其lambda表达式里,让it关键字能引用它
let与apply比较,let会把接受者传给lambda,而apply什么都不传,匿名函数执行完,apply会返回
当前接受者,而let会返回lambda的最后一行*/
data.let {
}
//run 返回lambda结果
/*光看作用域行为,run和apply差不多,但与apply不同,run函数不返回接受者,
run函数不返回接受者,run返回的是lambda结果,也就是true或者false
*/
val ss = data.run {
contains("a")
}
//run可以接受函数的引用
data?.run(::isLong)
.run (::showMessage)
.run(::println)
//with
with("12345"){
println(this)
}
//also函数和let函数功能相似,和let一样,also也是把接受者作为值参传给lambda,但有一点
//不同:also返回接受者对象,而let返回lambda结果。因为这个差异,also尤其适合针对同一原始
//对象,利用副作用做事,既然also返回的是接受者对象,你就可以基于原始接受者对象执行额外的
//链式调用。
data.also {
println()
}.also {
}
//和其他标准函数有点不一样,takeif 函数需要判断lambda中提供的条件表达式,'给出true或者false
//结果。如果判断结果是true,从takeif函数返回接受者对象,如果是flase,则返回null,
//如果需要判断某个条件是否满足,再决定是否可以赋值变量或者执行某项任务,takeif就非常有用,
//概念上讲,takeif函数类似于if语句,但它的优势是可以直接在对象实例上调用,避免了临时变量赋值的麻烦。