Kotlin基础(2)

幻昼 2021年03月02日 241次浏览

泛型

? extend T   =>  out T 协变 传入只能是其子类  只能get

? super  T   =>  in  T 逆变 传入只能是其父类  可以get/set

Object 相当于 Any?

String? 最高父类 Any?

fun main() {

    var destNumber = arrayOf<Number>()
    var srcDouble = arrayOf<Double>(1.2, 3.2, 24.2)
    println(copyIn(destNumber,srcDouble))

    copyOut(destNumber, srcDouble)

}

//逆变super
fun <T> copyIn(dest: Array<in T>, src: Array<T>) {//消费者
// PECS Producer extends Consumer Super
//    取                存
//    ?extends         ? super
//    out 取出来        in  存进去
//        协变              逆变
    src.forEachIndexed { index, value -> dest[index] = src[index] }
}


//协变
fun <T> copyOut(dest: Array<T>, src: Array<out T>) {//生产者
    src.forEachIndexed { index, value -> dest[index] = src[index] }
}

高阶函数、lambda

将函数⽤作参数或返回值的函数

fun test(a:String ,display: (String)->Unit){//lambda 也是函数
display(a)
}

test("zero"){

}
//lambda
var temp: (Int,Int) -> Int

var sum = {x:Int,y:Int -> x +y}
com.zero.lib.kotlin.basic01.sum(1,2)
var tmp1:(Int) -> Unit

tmp1 ={ println("$it")
       it+2
      }//默认一个参数

扩展函数

T.xxx() {

}

常用高阶函数

//常用的高阶函数
run{
//执行一块独立代码块
}

val str = "kolit"
str.length
str.run {
length
}

with(str){

}

str.apply {

}
.apply {

}
.apply {
length
}


str.also {

it.length
}

str.let {
it.reversed()
}

val st1 = str.takeIf {
it.startsWith("sko")
}

lazy {  }

协程

协程是轻量级的线程, 开销成本相比线程是十分廉价的。

创建协程

通常用launch 、aysnc、 runBlocking启动协程

// 启动一个全局协程
GlobalScope.launch { // 在后台启动⼀个新的协程并继续
    delay(1000L)
    println("World!")
}


runBlocking { // 但是这个表达式阻塞了主线程
	delay(2000L) // ……我们延迟 2 秒来保证 JVM 的存活
}

在主协程用调用 job.join() ,会等待到子协程执行完。

coroutineScope作用域构建器用来设定协程作⽤域 ,它会创建⼀
个协程作⽤域并且在所有已启动⼦协程执⾏完毕之前不会结束。

suspend 修饰的函数为挂起函数,只能在协程内部使用。

取消协程

调用 job.cancel() 来取消。取消是协作的,调用了不一定取消,例如正在计算,可以在协程内部使用isActive表达式判断是不是已经取消。

有时取消了还要进行操作,可以用,但这是不阻塞的,有可能finally的未执行完就退了,此时可以用 withContext(NonCancellable) {……} 进行阻塞等待。

try{

}finally{

}

// 也可以设置超时
withTimeout(1300L) {
    repeat(1000) { i ->
        println("I'm sleeping $i ...")
        delay(500L)
	}
}

组合挂起函数

挂起函数在协程内部是顺序的,想要并发需使用aysnc块,返回结果需要用 .await()获取

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // 假设我们在这⾥做了⼀些有⽤的事
    return 13
} 
suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // 假设我们在这⾥也做了⼀些有⽤的事
    return 29
}
val time = measureTimeMillis {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")

// 惰性启动
val time = measureTimeMillis {
    val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
    val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
    one.start() // 启动第⼀个
	two.start() // 启动第⼆个
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
推荐使用方法
suspend fun concurrentSum(): Int = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    one.await() + two.await()
}

val time = measureTimeMillis {
	println("The answer is ${concurrentSum()}")
}
println("Completed in $time ms")

调度器

调度线程用那个线程跑

调度器使用的线程
runBlocking(默认)使用父层的上下文,main
Dispatchers.Unconfinedmain
Dispatchers.DefaultDefaultDispatcher-worker-1
newSingleThreadContext("MyOwnThread")MyOwnThread

when

when(code){
    1 -> {xxx}
    2 -> {xxx}
    else -> {xxx}
}

伴生对象

相当于静态变量

companion object {
	const val TAG = "Jin"
}

单例

private object Holder {
	val INSTANCE = ApiClient()
}
companion object {
	val instance by lazy { Holder.INSTANCE }
}

作用域函数

letrunwithapplyalso

区别

  • 引用上下文对象的方式
  • 返回值

上下文对象

this:runwithapply

it:letalso // 当将上下文对象作为参数传递时,可以为上下文对象指定在作用域内的自定义名称。

返回值

  • applyalso 返回上下文对象。
  • letrunwith 返回 lambda 表达式结果.

主要区别表

函数对象引用返回值是否是扩展函数
letitLambda 表达式结果
runthisLambda 表达式结果
run-Lambda 表达式结果不是:调用无需上下文对象
withthisLambda 表达式结果不是:把上下文对象当做参数
applythis上下文对象
alsoit上下文对象

以下是根据预期目的选择作用域函数的简短指南:

  • 对一个非空(non-null)对象执行 lambda 表达式:let
  • 将表达式作为变量引入为局部作用域中:let
  • 对象配置:apply
  • 对象配置并且计算结果:run
  • 在需要表达式的地方运行语句:非扩展的 run
  • 附加效果:also
  • 一个对象的一组函数调用:with