字符串操作
- == 判断值相等
- ===判断引用相等
- subString 支持 until表达
- replace支持lambda表达式
- split支持分割赋值
- forEach可以遍历字符串的每个字符
const val t1 = "hello great huya com"
const val t2 = "tik ,tok , cat ,fish"
const val t3 = "hello china"
const val t4 = "hch"
const val t5 = "hch"
var t6 = "hch".capitalize()
const val t7 = "Hch"
fun main() {
var index = t1.indexOf("huya")
println(t1.substring(0 until index))
var (a,b,c,d) = t2.split(",")
println("$a $b $c $d")
var temp = t3.replace(Regex("[china]")){
when(it.value){
"c"->"1"
"h"->"2"
"i"->"3"
"n"->"4"
"a"->"5"
else -> it.value
}
}
println(temp)
println(t4 == t5) //true
println(t4 === t5) // true ,同一个字符串在内存中指向的是同一个常量地址
println(t6 == t7) //true
println(t6 === t7) //false
t1.forEach { print("$it ") }
}
数字类型
- 所有数字类型都是有符号的
- toIntOrNull/toDoubleOrNull等安全转化函数,不会抛出异常
- 数字格式化 %.3f, %.2l
- double转int toInt / roundToInt
import kotlin.math.roundToInt
fun main() {
var a = "1.11".toIntOrNull()
println(a?.javaClass)
var b = "%.3f"
println(b.format(8.95678))
println(8.95678.toInt())
println(8.95678.roundToInt())
}
基础函数库
很多的基础函数如apply , also , let , run , with等,他们位于standard.kt文件中.
功能上具有相似性,在表现上主要有两点不同
- 函数的函数体中传入的参数不同,一般都是this/it,it只能对参数进行处理,this能够访问调用对象的属性和方法.
- 函数的返回值不同,有些返回的是最后一行的结果result,有些返回的是this.
区别总结如下表格
| 函数名 | 入参 | 返回值 |
|---|---|---|
| apply | this | this |
| also | it | this |
| let | it | result |
| run | this | result |
| with | this | result |
关键区别分析 T.()->Unit与(T)->Unit
以also 和apply的源码分析来分析
- 可以看出如果block的定义是T.()->Unit,则默认传入this作为block入参,如果block的定义是(T)->Unit,则传入it作为入参
- T.()->Unit 等同于为T定义了一个基于T的无参数的扩展函数,所以在函数体内可以直接通过this或省略来访问T代表的对象
- (T) -> Unit通过形参T可将对象作为实参传给函数,所以函数体里能通过it或者指定名称的方式来访问该对象
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
apply
- 返回的当前的接受者对象
- block的入参是this
- 对对象进行多个赋值,类似于建造者模式
import java.io.File
fun main() {
var file = File("a").apply {
println(this.hashCode() )
setExecutable(false)
setReadable(true)
setWritable(true)
}
println(file.hashCode())
}
// this 和 file是同一个对象
also
- 与apply功能类似
- block的入参是it
- 返回this
let
- let返回的是lambda表达式的最后一行结果result
- let与elvis结合可以用于替换 if/else
var aInt = "hello".let { it.length + 20 }
println(aInt)
//let + elvis
fun init(input:String?):String{
return input?.let { "$input .. hello" } ?: "unkonwn"
}
//用if /else实现的写法
fun init2(input:String?):String{
if (input == null){
return "unkonwn"
}else{
return "$input .. hello"
}
}
run
- 执行某个函数,且返回值为函数最后一行结果
- 可以链式执行多个函数,每个函数输入为上一个的输出
- 可以执行函数引用
println("I am Chinese".
run { contains("am") }.
run { if (this) "abc" else "def" })
println("I am Chinese".run(::contains).run (::check))
fun contains(input:String?):Boolean?{
return input?.contains("am")
}
fun check(b:Boolean?):String{
return "abc".takeIf { b?:false } ?: "def"
}
with
- 与run功能类型
- 输入第一个参数为值参,第二个为处理函数
var hello = with("hello world") {
this.replace(Regex("[aeiou]" , )){
when(it.value){
"a"->"0"
"e"->"1"
"i"->"2"
"o"->"3"
"u"->"4"
else -> it.value
}
}
}
println(hello)
takeIf
- 如果takeIf中的函数的结果为true,则返回接受者,否则返回null
- 实用与条件判断
- 可以用于三元表达式的替换
println( File("test.txt").takeIf {
println(it.absolutePath)
it.exists()
}?.readText() )
b.takeIf{a} ?:c
takeUnless
用法与takeIf相反