Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

В случае объектного подхода, при вызове метода у объекта, у нас есть его аргументы, но кроме того мы имеем явный (в случае Python) или неявный параметр, представляющий экземпляр вызываемого класса (здесь и далее  далее все примеры написаны на Kotlin):

Code Block
class A{
    fun doSomething(){
        println("ThisЭтот methodметод isвызывается calledна on $this")
    }
}

Вложенные классы и замыкания все несколько усложняют:

Code Block
interface B{
    fun doBSomething()
}

class A{
    fun doASomething(){
        val b = object: B{
            override fun doBSomething(){
                println("ThisЭтот methodметод isвызывается called onна $this insideвнутри ${this@A}")
            }
        }
        b.doBSomething()
    }
}

В данном случае, есть два неявных this для функции doBSomething - один соответствует экземпляру класса B, а другой возникает от замыкания экземпляра A. То же самое происходит в намного более часто встречающемся случае лямбда-замыкания. Важно отметить, что this в данном случае работает не только как неявный параметр, но и как область или контекст для всех функций и объектов, вызываемых в лексической области определения. Так что метод  метод doBSomething на самом деле имеет доступ к любым, открытым или закрытым, членам класса A, так же как и к членам самого B.

...

Kotlin дает нам совершенно новую "игрушку" - функции-расширения. (Примечание от формалиста:  на самом деле не такие уж новые, в C# они тоже есть). Вы можете определить функцию вроде A.doASomething() где угодно в программе, не только внутри A. Внутри этой функции у нас есть неявный this-параметр, называемый получателем, который указывает указывающий на экземпляр A на котором метод вызывается:

Code Block
class A

fun A.doASomthing(){
    println("ThisЭтот extensionметод-расширение methodвызывается isна called on $this")
}

fun main(){
    val a = A()
    a.doASomthing()
}

...

В этом примере обе функции можно было возможно вызвать без дополнительного "a." в начале, потому что функция with помещает весь код последующего блока внутрь контекста a. Это значит что все функции в этом блоке вызываются так, как если бы они вызывались на (явно переданном) объекте a.

...

Также, структурированная конкурентность дает (question) дает отличный пример контекстно-ориентированной архитектуры:

...

Здесь doSomeWork - это контекстная функция, но определенная за пределами ее контекста. Методы launch создают два вложенных контекста, которые эквивалентны лексическим областям соответствующих функций (в данном случае оба контекста имеют один и тот же тип, поэтому внутренний контекст затеняет внешний). Хорошей отправной точкой для изучения сопрограмм в Kotlin является официальное руководство.

...

Существует широкий класс задач для Kotlin, на которые обычно ссылаются как на задачи построения DSL (Domain Specific Language). Под DSL при этом понимается некоторый код, который обеспечивает обеспечивающий дружественный пользователю построитель какой-либо то сложной внутри структуры. На самом деле использование термина DSL здесь не совсем корректно, т.к. в таких случаях просто используется базовый синтаксис Kotlin без каких-либо специальных ухищрений - но давайте все-таки использовать этот распространенный термин.

...

В этом примере лексическая область определяет свой контекст (что логично, т.к. он представляет раздел GUI и его внутреннее устройство), и имеет доступ к родительским контекстам.

...