2017-05-29 66 views
3

是否可以使用下面的AsyncResult類來防止在UserDataAppResult和CreateUserResult中重新定義InFlight,Error和InFlight?如何使密封類在kotlin中通用?

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

上面的代碼可能看起來像這樣嗎?

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密封類層次結構並引入新類型。

回答

1

這在Kotlin中是不可能的。你使用的每種類型都必須有明確聲明的類。即使在超類中聲明嵌套類時,編譯器也不會隱式創建類。我建議你重寫代碼,將兩個基於繼承的層次結構合併爲兩個合併繼承和合成中的一個,或者只是以某種方式重構層次結構,例如(我假設一個確切的如果不是Loaded):

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) 
    } 
} 
+0

謝謝,我會嘗試一下你的方法,看看我如何繼續下去。 –