2016-10-29 1 views
1

Как я могу ленить инициализировать поле и выполнить утверждение на нем?Можно ли лениво инициализировать имущество и утверждать его?

Я попытался

val table: Array<FormatInfo> by lazy { 
    val t = arrayOf(...) 
    assert(table.size == FORMAT_COUNT, { System.err.println("GLI error: format descriptor list doesn't match number of supported formats") }) 
    t 
} 

Но он идет переполнение:

java.lang.StackOverflowError 
    at gli.GliKt$table$2.invoke(gli.kt:451) 
    at gli.GliKt$table$2.invoke(gli.kt) 
    at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131) 
    at gli.GliKt.getTable(gli.kt) 
    at gli.GliKt$table$2.invoke(gli.kt:693) 
    at gli.GliKt$table$2.invoke(gli.kt) 
    at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131) 
    at gli.GliKt.getTable(gli.kt) 
    at gli.GliKt$table$2.invoke(gli.kt:693)... 

Как я могу решить?

+0

Btw, я думаю, что это называется 'property', а не' field' – voddan

+0

Не скрывайте код, который вызывает исключение. Не заставляйте нас угадывать, что вы делаете неправильно. –

+0

Исправлено оба, спасибо – elect

ответ

3

Трассировка стека выглядит так, будто вы вызываете свойство изнутри лямбда lazy {}, что, очевидно, заставляет его раздавить.

Это должно работать:

val table: Array<FormatInfo> by lazy { 
    val t = arrayOf(...) 
    myAssert(t) 
    t 
} 
+0

Дерьмо, я пропустил это, спасибо! Кстати, это правильный способ лениво инициировать «свойство» и утверждать его или есть лучший способ? – elect

+0

Глядя на ваш пример, я не могу понять, почему вы делаете это свойство ленивым вообще. Я бы пошел с нормальной собственностью. – voddan

+0

Если вы хотите применить материал (например, утверждает) к чему-то, возвращаемому в лямбда, я рекомендую использовать 'apply' вместо переменной temp. Например: 'val table: Array by lazy {arrayOf (...). apply {assert (this ...)}}'. – mfulton26