2017-11-20 134 views
9
object Foo : CharSequence by Foo.X { 
    val X = "" 
} 

produkuje"Zmienna musi być zainicjowany" błąd podczas delegowania do zainicjowany własności

Variable 'X' must be initialized 

Ale to jest! Kod powinien być przetłumaczony na coś w rodzaju:

object Foo : CharSequence { 
    val X = "" 
    override val length get() = Foo.X.length 
    override operator fun get(index: Int): Char = Foo.X[index] 
    override fun subSequence(startIndex: Int, endIndex: Int) = Foo.X.subSequence(startIndex, endIndex) 
} 

który działa dobrze.

Jaki jest powód błędu i czy istnieje obejście problemu? W prawdziwym inicjowaniu kodu jest nietrywialny i Foo musi być object (w rzeczywistości obiektem towarzyszącym), a nie class.

Odpowiedz

1

Spekuluję, że używanie delegacji klas do obiektu jest nieco nieoczywiste, więc prawdopodobnie jest to esencja , dlatego.

Obejście polega na delegowaniu bezpośrednio do instancji String. Ten kod działa dla mnie:

fun main(args: Array<String>) { 
    println("Hello, world! ${Bar.Foo.indexOf("z")}") // Prints "2" 
} 

class Bar { 
    companion object Foo : CharSequence by String(StringBuilder("xyzzy")) { 
    } 
} 

marginesie: String w Kotlin ma konstruktora, który przyjmuje parametr String. Dziwne, to.

+2

Odnośnie ostatniego zdania: odpowiedni konstruktor Java stracił swoje główne zastosowanie od wersji 7u6 (jeśli dobrze pamiętam, ale powinno być coś w tym zakresie) i nadal istnieje tam kompatybilność wsteczna. Kotlin nie ma potrzeby go kopiować. –

+0

Tak, zdałem sobie sprawę, że nie ma potrzeby używania tego konstruktora w powyższym kodzie. Jest to odpowiednik: 'obiekt towarzyszący Foo: CharSequence przez" xyzzy "' –