SoFunction
Updated on 2025-04-06

One-time application record of Kotlin type safety builder

In the relevant application framework guided by Android, a Resource class is used to represent the status and results of network requests.

// 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)
}

In most cases, we use it in activity

private val testViewModel : TestViewModel by viewModels()

private fun getUserInfo(uid: String) {
 (this, Observer {
  when () {
    -> TODO()
    -> TODO()
    -> TODO()
  }
 })
 (uid)
}

I feel so annoying to write too much like this. Every time I do it when(). Is there any more fun writing? For example?

private fun getUserInfo(uid: String) {
 (this, Observer {
  success {
   
  }
  error {
   
  }
  loading {
   
  }
 })
 (uid)
}

When I just need to deal with success, I can not write error/loading.

kotlin's type safety builder can do it, let's take a look at the official example

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

fun html(init: HTML.() -&gt; Unit): HTML {
 val html = HTML() // Create a receiver object ()  // Pass the recipient object to the lambda return html
}

html {  // The lambda with the receiver starts from this body() // Call a method of the receiver object}

Let’s analyze first, what we need is an object that implements the Observer interface.

So we first define a class to implement the Observer interface

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

Implement a top-level function and return a ResourceObserver object

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

Call this function to get the ResourceObserver object

resourceObserver {
 //Can call member functions in the object here}

So my implementation is

class ResourceObserver<T: Any> : Observer<Resource<T>> {
 private var success: (<T>.() -> Unit)? = null
 private var error: (.() -> Unit)? = null
 private var loading: (<T>.() -> Unit)? = null
 
 fun success(s: (<T>.() -> Unit)) {
  success = s
 }
 
 fun error(e: .() -> Unit) {
  error = e
 }
 
 fun loading(l: <T>.() -> Unit) {
  loading = l
 }
 
 override fun onChanged(t: Resource<T>) {
  when(t) {
   is  -> success?.invoke(t)
   is  -> error?.invoke(t)
   is  -> loading?.invoke(t)
  }
 }
}

Summarize

This is the article about the application record of Kotlin type safety builder. For more related content on Kotlin type safety builder, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!