首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在kotlin中使密封类成为泛型?

如何在kotlin中使密封类成为泛型?
EN

Stack Overflow用户
提问于 2017-05-29 21:31:10
回答 4查看 10.5K关注 0票数 17

是否可以使用下面的AsyncResult类来防止在UserDataAppResult和CreateUserResult中重新定义InFlight、Error和InFlight?

代码语言:javascript
复制
//TODO: use this to make the below classes generic?
sealed class AsyncResult{
  object InFlight : AsyncResult()
  data class Error(val errorMessage: String) : AsyncResult()
  data class Loaded<out T>(val users: T) : AsyncResult()
}

sealed class UserDataAppResult : AppResult() {
  object InFlight : UserDataAppResult()
  data class Error(val errorMessage: String) : UserDataAppResult()
  data class Loaded(val users: List<User>) : UserDataAppResult()
}

sealed class CreateUserResult : AppResult() {
  object InFlight : CreateUserResult()
  data class Error(val errorMessage: String) : CreateUserResult()
  data class Loaded(val users: User) : CreateUserResult()
}

上面的代码可能是这样的吗?

代码语言:javascript
复制
sealed class AsyncResult{
  class InFlight : AsyncResult()
  data class Error(val errorMessage: String) : AsyncResult()
  data class Loaded<out T>(val users: T) : AsyncResult()
}

sealed class UserDataAppResult : AsyncResult()
sealed class CreateUserResult : AppResult()

val activeUsers: Flowable<UserDataAppResult> = appDatabase.userDao().getActiveUsers(appSettings.currentLanguage.ordinal)
    .map<UserDataAppResult> { UserDataAppResult.Loaded(it) }
    .onErrorReturn { UserDataAppResult.Error(it.localizedMessage) }
    .startWith(UserDataAppResult.InFlight)
    .observeOn(AndroidSchedulers.mainThread())
    .share()

fun createUser(): Flowable<CreateUserResult> {

  val userId = UUID.randomUUID().toString()
  val user = User()
  user.id = userId
  return appDatabase.userDao().insertAll(user)
      .map <CreateUserResult> { CreateUserResult.Loaded(user) }
      .onErrorReturn { CreateUserResult.Error(it.localizedMessage) }
      .startWith(CreateUserResult.InFlight)
}

目前没有找到UserDataAppResult.Error,这是有道理的。但是是否可以重用AppResult密封的类层次结构并引入新类型。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-05-30 17:41:44

这在Kotlin是不可能的。您使用的每个类型都必须在某处有一个显式声明的类。即使在超类中声明了嵌套类,编译器也不会隐式创建类。

对于您的问题,我建议您将代码从组合两个基于继承的层次结构重写为两个组合继承和组合的层次结构之一,或者只是以某种方式重构层次结构,例如(我认为结果的确切实例在不是Loaded的情况下与您无关):

代码语言:javascript
复制
sealed class AsyncResult {
    object InFlight : AsyncResult()
    data class Error(val errorMessage: String) : AsyncResult()
    sealed class Loaded<out T>(val result: T) : AsyncResult() {
        sealed class UserDataAppResult(users: List<User>) : Loaded<List<User>>(users)
        sealed class CreateUserResult(user: User) : Loaded<User>(user)
    }
}
票数 7
EN

Stack Overflow用户

发布于 2019-12-20 17:30:38

您的Object在Kotlin中不能有泛型类型,但只需遵循以下示例即可解决此问题:

代码语言:javascript
复制
sealed class ResponseState<out T> {
    object Loading : ResponseState<Nothing>()
    data class Error(val throwable: Throwable) : ResponseState<Nothing>()
    data class Success<T>(val item: T) : ResponseState<T>()
}

写作:

代码语言:javascript
复制
val state = MutableLiveData<ResponseState<MessageModle>>() 


_state.postValue(ResponseState.Loading)

myNetworkCall { response, e
  if (e != null) _state.postValue(ResponseState.Error(e))
  else _state.postValue(ResponseState.Success(response))
}

阅读:

代码语言:javascript
复制
state.observe(..., {state -> 
  when(state) {
    Loading -> showLoading()
    is Error -> showError(state.throwable)
    is Success -> onSuccess(state.item)
  }
}
票数 36
EN

Stack Overflow用户

发布于 2019-12-04 11:48:02

通过谷歌指南:https://developer.android.com/jetpack/docs/guide

代码语言:javascript
复制
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, var refreshing: Boolean = false) : Resource<T>(data)
    class Error<T>(data: T? = null, message: String) : Resource<T>(data, message)
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44243763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档