почему есть «по» для расширенного класса и ограничено в определении функции - PullRequest
0 голосов
/ 25 февраля 2019

наткнулся на образец с классом и функцией и попытался понять там синтаксис Колтина,

  1. что это делает IMeta by dataItem?посмотрел на https://kotlinlang.org/docs/reference/classes.html#classes и не видел, как использовать by в производном классе

  2. , почему reified требуется в inline fun <reified T> getDataItem()?Если кто-то может дать образец для объяснения reified?

    class DerivedStreamItem(private val dataItem: IMeta, private val dataType: String?) :
        IMeta by dataItem {
    
    override fun getType(): String = dataType ?: dataItem.getType()
    fun getData(): DerivedData? = getDataItem()
    
    private inline fun <reified T> getDataItem(): T? = if (dataItem is T) dataItem else null
    

    }

для справки, скопируйте соответствующие определения здесь:

interface IMeta {
    fun getType() : String
    fun getUUIDId() : String
    fun getDataId(): String?
}

class DerivedData : IMeta {
    override fun getType(): String {
        return ""  // stub
    }

    override fun getUUIDId(): String {
        return ""  // stub
    }

    override fun getDataId(): String? {
        return ""  // stub
    }
}

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

почему inline fun <reified T> getDataItem() требуется в *1003*?Если кто-то может дать образец для объяснения reified?

Есть хорошая документация по параметрам reified type , но я постараюсь немного ее свести.

Ключевое слово reified в Kotlin используется, чтобы обойти тот факт, что JVM использует стирание типа для универсального.Это означает, что во время выполнения всякий раз, когда вы ссылаетесь на универсальный тип, JVM имеет нет представления о том, что представляет собой фактический тип.Это только во время компиляции.Так что T в вашем примере ... JVM понятия не имеет, что это значит (без формулировки, которую я объясню).

В своем примере вы заметите, что вы также используете inline ключевое слово.Это говорит Kotlin, что вместо вызова функции при ссылке на нее нужно просто вставить тело функции inline.Это может быть более эффективным в определенных ситуациях.Итак, если Kotlin уже собирается копировать тело нашей функции во время компиляции, почему бы просто не скопировать класс, который также представляет T?Здесь используется reified.Это говорит Kotlin ссылаться на фактический конкретный тип T и работает только с inline функциями.

Если вы удалите ключевое слово reified из вашего примера, вы получите ошибку:Msgstr "Невозможно проверить, например, стёртый тип: T".Реализуя это, Kotlin знает, что такое фактический тип T, что позволяет нам сделать это сравнение (и полученное умное приведение) безопасно.

0 голосов
/ 26 февраля 2019

(Поскольку вы задаете два вопроса, я собираюсь ответить на них отдельно)

Ключевое слово by в Kolin используется для делегирования.Существует два вида делегирования:

1) Реализация делегированием (иногда называемое делегированием классов)

Это позволяет реализовать интерфейс и делегировать вызовы этого интерфейса дляконкретный объект.Это полезно, если вы хотите расширить интерфейс, но не реализовать каждую его часть.Например, мы можем расширить List, делегировав его и позволив нашему вызывающему объекту предоставить нам реализацию List

class ExtendedList(someList: List) : List by someList {
   // Override anything from List that you need
   // All other calls that would resolve to the List interface are 
   // delegated to someList   
}

2) Делегирование свойства

Это позволяет выполнять аналогичную работу, но со свойствами.Мой любимый пример - lazy, который позволяет вам лениво определять свойство.Ничего не создается, пока вы не ссылаетесь на свойство, а результат кэшируется для более быстрого доступа в будущем.

Из документации Kotlin:

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...