Как аргумент по умолчанию и @JvmOverloads работают на Kotlin?

Когда мы развлекались с Kotlin вот так

fun foo(bar: Int = 0, baz: Int) { /* ... */ }

foo(baz = 1) // The default value bar = 0 is used

Итак, в java нам нужно написать это так, например.

не нужно писать

void foo(int bar, int baz){
...
}

void foo(int baz){
foo(0,baz);
}

Давайте представим, что у нас есть 10+ параметров. Интересно, как Котлин справляется с этим. Будет ли Kotlin генерировать все возможные методы? Или он просто генерирует метод, который действительно используют программисты?


person UmAnusorn    schedule 03.09.2017    source источник


Ответы (3)


Не будет сгенерировано 2^N перегрузок. Как указано в документах,

Для каждого параметра со значением по умолчанию будет создана одна дополнительная перегрузка, в которой этот параметр и все параметры справа от него в списке параметров удалены.

Для функции с параметрами по умолчанию, скажем,

 fun foo(bar: Int = 1, baz: Int = 2, qux: Int = 3) { /*...*/ }

это вызовет перегрузку

 foo()
 foo(bar)
 foo(bar, baz)
 foo(bar, baz, qux)
person hotkey    schedule 03.09.2017

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

Указывает компилятору Kotlin создавать перегрузки для этой функции, которые заменяют значения параметров по умолчанию.

Если метод имеет N параметров, M из которых имеют значения по умолчанию, генерируется M перегрузок: первый принимает N-1 параметров (все, кроме последнего, принимающего значение по умолчанию), второй принимает N-2 параметра и т. д. на.

person Rafal G.    schedule 03.09.2017

Когда у вас есть функция с параметрами по умолчанию, Kotlin генерирует синтетическую функцию с требуемыми параметрами и дополнительным Int в качестве последних параметров и выполняет некоторые битовые манипуляции.

Пример функции Котлина:

fun lotsOfParameters(a: String = "Default",
                     b: Byte = 2,
                     c: Char = 'p',
                     d: Boolean = false,
                     e: Any = true,
                     f: Int = 2) {
}

Скомпилированный Java-код:

public static final void lotsOfParameters(@NotNull String a, byte b, char c, boolean d, @NotNull Object e, int f) {
  Intrinsics.checkParameterIsNotNull(a, "a");
  Intrinsics.checkParameterIsNotNull(e, "e");
}

// $FF: synthetic method
// $FF: bridge method
public static void lotsOfParameters$default(String var0, byte var1, char var2, boolean var3, Object var4, int var5, int var6, Object var7) {
  if ((var6 & 1) != 0) {
     var0 = "Default";
  }

  if ((var6 & 2) != 0) {
     var1 = 2;
  }

  if ((var6 & 4) != 0) {
     var2 = 'p';
  }

  if ((var6 & 8) != 0) {
     var3 = false;
  }

  if ((var6 & 16) != 0) {
     var4 = true;
  }

  if ((var6 & 32) != 0) {
     var5 = 2;
  }

  lotsOfParameters(var0, var1, var2, var3, var4, var5);
}
person Mibac    schedule 03.09.2017