Kotlin类型安全构建器的一次运用记录

在android官方指导的相关应用框架中,用到一个Resource类来表示网络请求的状态与结果

// A generic class that contains data and status about loading this data.
sealed class Resource<T>(
 val data: T? = null,
 val message: String? = null
) {
 class Success<T>(data: T) : Resource<T>(data)
 class Loading<T>(data: T? = null) : Resource<T>(data)
 class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
}

大多数情况下我们在activity里面是这样用的

private val testViewModel : TestViewModel by viewModels()

private fun getUserInfo(uid: String) {
 testViewModel.userInfoData.observe(this, Observer {
  when (it.status) {
   Status.SUCCESS -> TODO()
   Status.ERROR -> TODO()
   Status.LOADING -> TODO()
  }
 })
 testViewModel.setUserId(uid)
}

这样写多了感觉好烦,每次都是when(),有没有更爽的写法呢?比如这样?

private fun getUserInfo(uid: String) {
 testViewModel.userInfoData.observe(this, Observer {
  success {

  }
  error {

  }
  loading {

  }
 })
 testViewModel.setUserId(uid)
}

当我只需要处理success的时候,我可以不写error/loading情况。

kotlin的类型安全构建器可以做到,我们先看下官方的示例

class HTML {
 fun body() { …… }
}

fun html(init: HTML.() -> Unit): HTML {
 val html = HTML() // 创建接收者对象
 html.init()  // 将该接收者对象传给该 lambda
 return html
}

html {  // 带接收者的 lambda 由此开始
 body() // 调用该接收者对象的一个方法
}

先分析下,我们需要的是一个实现了Observer接口的对象。

所以我们先定义一个类来实现Observer接口

class ResourceObserver<T: Any> : Observer<Resource<T>> {
 override fun onChanged(t: Resource<T>) {
  when(t) {
   is Resource.Success -> TODO()
   is Resource.Error -> TODO()
   is Resource.Loading -> TODO()
  }
 }
}

实现一个顶层函数,返回一个ResourceObserver对象

fun <T: Any> resourceObserver(init: ResourceObserver<T>.() -> Unit): ResourceObserver<T> {
 val observer = ResourceObserver<T>()
 observer.init()
 return observer
}

调用该函数即可得到ResourceObserver对象

resourceObserver {
 //在此处可以调用对象内的成员函数
}

所以我的实现是

class ResourceObserver<T: Any> : Observer<Resource<T>> {
 private var success: (Resource.Success<T>.() -> Unit)? = null
 private var error: (Resource.Error.() -> Unit)? = null
 private var loading: (Resource.Loading<T>.() -> Unit)? = null

 fun success(s: (Resource.Success<T>.() -> Unit)) {
  success = s
 }

 fun error(e: Resource.Error.() -> Unit) {
  error = e
 }

 fun loading(l: Resource.Loading<T>.() -> Unit) {
  loading = l
 }

 override fun onChanged(t: Resource<T>) {
  when(t) {
   is Resource.Success -> success?.invoke(t)
   is Resource.Error -> error?.invoke(t)
   is Resource.Loading -> loading?.invoke(t)
  }
 }
}

总结

到此这篇关于Kotlin类型安全构建器的一次运用记录的文章就介绍到这了,更多相关Kotlin类型安全构建器运用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Kotlin基本类型自动装箱出现问题解决办法

    Kotlin基本类型自动装箱出现问题解决办法 问题 在Kotlin官方文档介绍基本类型时,给我们说明了在有些情况下会对基本类型自动进行装箱操作. 但是具体是如何进行装箱,以及何时进行装箱缺没有提供详细介绍.只是提供了一个例子,如下: val a: Int = 10000 print(a === a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) /

  • Kotlin类型系统竟如此简单

    Quote 在学习 Kotlin 的过程中,对 Kotlin 的类型系统产生了好奇,Kotlin 是否存在类似于 Java 中 Object 的公共基类?Kotlin 中是否也有类似于 Java 基础类型这样的单独分支?在研究一番过后,博主发现相较于 Java,Kotlin 交出了更为满意的答案,而且出乎意外地简单,只需要遵循简单的规则,便能理解整个类型系统. Any Any 等同于 Java 中的 Object 的概念,Any 在注释中这么写到: The root of the Kotlin

  • Java8中Optional类型和Kotlin中可空类型的使用对比

    本文主要给大家介绍了关于Java8中Optional类型和Kotlin中可空类型使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 在 Java 8中,我们可以使用 Optional 类型来表达可空的类型. package com.easy.kotlin; import java.util.Optional; import static java.lang.System.out; /** * Optional.ofNullable - 允许传递为 null 参数 *

  • Kotlin基础教程之数据类型

    Kotlin基础教程之数据类型 一切都是对象. 在Kotlin中一切都是对象.Kotlin有一些基本类型Boolean,Byte,Shot,Int,Long,Float,Double 在Kotlin中没有原始类型,以上这些类型都是对象,比如 运行结果如下 Kotlin支持16进制字面值,二进制字面值和科学记数法,官方文档中没有提到8进制 所有基本的几个数据类型不会进行显式类型转换,这一点尤为重要!那么如何进行转换呢?如下: 可以使用toLong,toInt,toShort,toChar等函数进行

  • Kotlin教程之基本数据类型

    Kotlin教程之基本数据类型的学习 基本类型 我们知道java的基本类型分为基本数据类型: int 普通整型 float 浮点型 char 字符型 short 短整型 byte 字节型 long 长整型 double 双精度 boolean 布尔型 和引用数据类型: class Type 类类型 interface Type 接口类型 array Type 数组类型 null Type 空类型 在 Kotlin 中,所有变量的成员方法和属性都是一个对象.一些类型是内建的,因为它们的实现是优化过

  • Kotlin 封装万能SharedPreferences存取任何类型详解

    Kotlin 封装万能SharedPreferences存取任何类型详解 /** * author: smart * time: 2016/10/26 * 封装好SharedPreferences 并使用 序列化和反序列化来存储数据 * 注意要在全局环境使用 */ class Preference<T>(val context : Context,val name : String,val default : T) : ReadWriteProperty<Any?,T>{ val

  • Kotlin基本类型自动装箱一点问题剖析

    问题 在Kotlin官方文档介绍基本类型时,给我们说明了在有些情况下会对基本类型自动进行装箱操作. 但是具体是如何进行装箱,以及何时进行装箱缺没有提供详细介绍.只是提供了一个例子,如下: val a: Int = 10000 print(a === a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!

  • Kotlin类型安全构建器的一次运用记录

    在android官方指导的相关应用框架中,用到一个Resource类来表示网络请求的状态与结果 // A generic class that contains data and status about loading this data. sealed class Resource<T>( val data: T? = null, val message: String? = null ) { class Success<T>(data: T) : Resource<T&

  • laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析

    本文实例讲述了laravel框架数据库操作.查询构建器.Eloquent ORM操作.分享给大家供大家参考,具体如下: 1.连接数据库 laravel连接数据库的配置文件位于config/database.php中,在其中connection字段中包含laravel所支持的数据库的配置信息,可以看到其中有主机.端口.数据库.用户名.密码等信息: 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'),

  • Laravel5.1 框架数据库查询构建器用法实例详解

    本文实例讲述了Laravel5.1 框架数据库查询构建器用法.分享给大家供大家参考,具体如下: 今儿个咱说说查询构建器.它比运行原生SQL要简单些,它的操作面儿也是比较广泛的. 1 查询结果 先来看看它的语法: public function getSelect() { $result = DB::table('articles')->get(); dd($result); } 查询构建器就是通过table方法返回的,使用get()可以返回一个结果集(array类型) 这里是返回所有的数据,当然

  • laravel5.6框架操作数据curd写法(查询构建器)实例分析

    本文实例讲述了laravel5.6框架操作数据curd写法(查询构建器).分享给大家供大家参考,具体如下: laravel5.6 数据库操作-查询构建器 <?php //laravel5.6 语法 demo示例 namespace App\Http\Controllers;//命名该控制App空间下名称 use Illuminate\Support\Facades\DB;//使用DB操作数据库 use App\Http\Controllers\Controller;//继承基础控制器 class

  • JavaScript库urlcat 之URL构建器库

    目录 1.作用 2.使用方法 在Node.js中使用 在Typescript中使用 在Deno中使用 3.API ParamMap:具有字符串键的对象 urlcat:构建完整的 URL query:构建查询字符串 subst:替换路径参数 join:使用一个分隔符连接两个字符串 urlcat 是一个小型的 JavaScript 库,它使构建 URL 非常方便并防止常见错误: 特性: 友好的 API 无依赖 压缩后0.8KB大小 提供TypeScript类型 1.作用 在调用 HTTP API 时

  • 一篇文章揭开Kotlin协程的神秘面纱

    前言 Kotlin协程提供了一种新的异步执行方式,但直接查看库函数可能会有点混乱,本文中尝试揭开协程的神秘面纱. 理论 它是什么 这是别人翻译: 协程把异步编程放入库中来简化这类操作.程序逻辑在协程中顺序表述,而底层的库会将其转换为异步操作.库会将相关的用户代码打包成回调,订阅相关事件,调度其执行到不同的线程(甚至不同的机器),而代码依然想顺序执行那么简单. 我的理解:子任务程协作运行,优雅的处理异步问题解决方案. 它能干什么? 我在做安卓开发,它能替换掉Handler,AsyncTask 甚至

  • 使用kotlin协程提高app性能(译)

    协程是一种并发设计模式,您可以在Android上使用它来简化异步执行的代码.Kotlin1.3版本添加了 Coroutines,并基于其他语言的既定概念. 在Android上,协程有助于解决两个主要问题: 管理长时间运行的任务,否则可能会阻止主线程并导致应用冻结. 提供主安全性,或从主线程安全地调用网络或磁盘操作. 本主题描述了如何使用Kotlin协程解决这些问题,使您能够编写更清晰,更简洁的应用程序代码. 管理长时间运行的任务 在Android上,每个应用程序都有一个主线程来处理用户界面并管理

  • Android使用Kotlin API实践WorkManager

    WorkManager 提供了一系列 API 可以更加便捷地规划异步任务,即使在应用被关闭之后或者设备重启之后,仍然需要保证立即执行的或者推迟执行的任务被正常处理.对于 Kotlin 开发者,WorkManager 为协程提供了最佳的支持.在本文中,我将通过实践 WorkManager codelab 为大家展示 WorkManager 中与协程相关的基本操作.那么让我们开始吧! WorkManager 基础 当您需要某个任务保持运行状态,即使用户切换到别的界面或者用户将应用切换到后台,甚至设备

  • Kotlin协程launch原理详解

    目录 正文 launch使用 launch原理 CoroutineStart中找invoke方法 startCoroutineCancellable逻辑 小结 正文 launch我们经常用,今天来看看它是什么原理. 建议: 食用本篇文章之前记得先食用Kotlin协程之createCoroutine和startCoroutine launch使用 launch我们应该很熟悉了,随便举个例子: fun main() { val coroutineScope = CoroutineScope(Job(

  • Kotlin Flow操作符及基本使用详解

    目录 一.Flow的基本概念 二.Flow的生命周期与异常处理 2.1 开始与结束 2.2 异常的处理 2.3 retry的处理 2.4 超时的处理 2.5 Flow的取消 三.Flow的创建方式 四.Flow的接收方式 五.Flow的转换操作符 5.1 基本操作符 5.2 特殊操作符 5.3 组合与展平操作符 5.4 切换线程 总结 一.Flow的基本概念 Kotlin 的 Flow 相信大家都或多或少使用过,毕竟目前比较火,目前我把Flow的使用整理了一下.希望和大家所学对照一下,能有所启发

随机推荐