2017-12-06 8 views
0

많은 시간에 제네릭 형식이 손실됩니다. 나는 코드를 단순화하고 싶지만 객체를 일반 타입으로 변환 할 수 없다. 이 문제 또는 다른 단순화 된 방법을 어떻게 해결할 수 있습니까? (I'm use kotlin 1.2)Kotlin 제네릭 형식 문제

sealed class SETTING(override val key: String) : SettingsKeyContract 

object optFirstLaunch : SETTING("first_launch"), SettingsKeyContractWithType<Boolean> { 
    override val defaults = true 
} 

object optNotifications : SETTING("notification_list"), SettingsKeyContractWithType<List<String>> { 
    override val defaults = emptyList<String>() 
} 

interface SettingsKeyContract { val key: String } 
interface SettingsKeyContractWithType<T : Any> : SettingsKeyContract { 

    val defaults: T 

    @Suppress("UNCHECKED_CAST") 
    fun get(): T?  = (App.getContentComponent()?.getSettings()?.get(key)?.value?.data as? T) 
    fun remove()  = (App.getContentComponent()?.getSettings())?.delete(key) 
    fun save(value: T) = (App.getContentComponent()?.getSettings()?.add(key, value)) 

} 

class OptionModel(@OPTIONS_ID optionId: Int, contract: SettingsKeyContract) 

val optionModel = OptionModel(1, optNotifications) 
when(optionModel.contract){ 
    is SettingsKeyContractWithType<List<String>> -> (optionModel.contract as SettingsKeyContractWithType<List<String>>).set(listOf("ring-1", "ring-2")) //error 
    is SettingsKeyContractWithType<Boolean> -> (optionModel.contract as SettingsKeyContractWithType<Boolean>).set(true) //error 
} 

오류 :

Cannot check for instance of erased type: SettingsKeyContractWithType<...> 

답변

2

유형의 삭제의 설명을 살펴보고 언어 참조의 일반적인 유형의 검사 입력하세요 : Type erasure and generic type checks합니다.

기본적으로 SettingsKeyContractWithType의 인스턴스에는 런타임시 실제 유형 인수에 대한 정보가 들어 있지 않기 때문에 이러한 종류의 검사를 수행 할 수 없습니다.

여기에서 시도 할 수있는 옵션은 make SettingsKeyContractWithType에 유형 인수의 표현을 명시 적으로 저장하는 것입니다. 그것은 구체적인 일반적인 유형을 표시 할 수 없기 때문에 간단한 KClassList<String>에 대한 KClass을 가질 수 없습니다 (적합하지 않는 것

을 그 여기에 설명 된대로, 슈퍼 타입 토큰의 기술을 사용하는 것을 고려 원하는 정말 무엇합니다. : (link)는.

당신은 SettingsKeyContractWithTypeTypeReference<T> 속성을 추가 구체화 유형 매개 변수와 인라인 공장 함수 내에서 그것을 채울 수 있습니다.