Начало новой деятельности

Я начал изучать Kotlin, запустив новое приложение, используя исключительно Kotlin и Android Studio 3.0 Beta, как настоящий мужчина (разработчик). Первое «втф?» было после того, как я закончил первый экран. Как, черт возьми, мне перейти к следующему действию? В Java я бы:

Intent intent = new Intent(this, NextActivity.class)
startActivity(intent)

Отлично, я могу перевести это на Kotlin, за исключением NextActivity.class… Теперь держитесь крепче. Это:

val intent = Intent(this, NextActivity::class.java)
startActivity(intent)

OMG, который выглядит как C++ в хорошие дни или оператор пространства имен C#. Или константы верхнего уровня Ruby. Это непохоже на то, что ссылается на класс Java. О, это то, что есть.

Получение ссылки на объект внешней области

Что от кого? Если вам нужно получить это из внутреннего замыкания, реализации анонимного класса, внутреннего класса и т. д. Знаете, например, когда вы создаете сеть и в обратном вызове хотите что-то сделать с Контекстом…

Допустим, мы находимся в MainActivity и делаем вызов (Java):

networkService.fetchEvents(new Callback<List<Event>() {
void onSuccess(List<Event> events) {
   Toast.makeText(MainActivity.this, "Events fetched", Toast.LENGHT_LONG).show();
   }
}

Как получить это в лямбда-выражении Kotlin? Просто, но странно, это:

fun onSuccess(events: List<Event>) {
    Toast.makeText(this@MainActivity, "Events fetched", Toast.LENGTH_LONG).show();
}

Я просто надеюсь, что не буду отправлять электронное письмо каждый раз, когда набираю это… Я не очень привык печатать @ в коде. Я слышал, что Objective-C любил @, но я пропустил этот странный язык.

Раз уж мы затронули тему малоизвестных внутренних блоков, Kotlin, мы должны поговорить об этом.

Лямбды в Котлине

Я остался позади с этими лямбда-вещами, потому что Android использовал древнюю версию Java, в которой их не было, поэтому я анонимно реализовывал интерфейсы. Например, когда вы добавляете прослушиватель кликов и тут же реализуете соответствующий интерфейс. Это довольно четкий синтаксис: все перед вами (Java).

tryAgain.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        checkLicense();
    }
});

Отлично, теперь приходит Котлин. Поскольку у OnClickListener есть только метон, вы можете:

tryAgain.setOnClickListener({
        checkLicense();
});

Что?! Куда все делось? Где мой параметр просмотра? Что, если он мне понадобится? Что ж..

tryAgain.setOnClickListener({
    view -> 
        checkLicense();
        view.setVisibility(GONE)
});

Вы также можете переименовать view в любое удобное для вас приложение или пропустить его, если оно вам не нужно. Отлично, это короче, но что, если метод должен что-то возвращать, например логическое значение?

interface RandomInterface {
    fun doSomething(): Boolean
}
tryAgain.setRandomInterface({
        doRandomStuff();
        true
});

Дафук? Без возврата? Неа… Можно было поставить, но если в конце, можно и не писать. Сбивает с толку? Много!

Хорошо, но что, если интерфейс имеет более одного метода? Что ж, тогда вам нужно реализовать его и создать экземпляр с помощью специального объекта с именем … object. Действительно, это ключевое слово в этом языке. Похоже, вы передаете аргумент, но на самом деле вы не можете его изменить, это object и ничего больше

Допустим, у нас есть (Java):

public interface FunctionToggler {
    void showFunction(boolean isVisible);
    boolean setDestination(int id);
}

И мы хотим установить это с помощью (также в Java):

void setFunctionToggler(boolean someParam, FunctionToggler functionToggler);

Давайте посмотрим, как это делает Kotlin:

someObject.setFunctionToggler(true, object: FunctionToggler() {
    override fun showFunction(isVisible: Boolean) {
         //..do stuff
    }
    overrider fun setDestination(id: Int): Boolean {
         //do other stuff
         return true
    }
}

Совершенно иначе, чем предыдущая вещь. За кулисами это все еще реализация на месте, но она более подробная, потому что интерфейс имеет более одной функции. Это для меня ясно, но другое…? И что с этим "объектом"?

Надеюсь, я запутал вас достаточно, чтобы начать копаться в синтаксисе Kotlin, потому что я очень быстро полюбил его. Меня не волнует, какое волшебство он творит, он прост в использовании и ускоряет мою разработку в 1,3 раза!*

*скорость разработки измеряется количеством «WTF/минута»