Основы программирования Котлина

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

fun main(args: Array<String>) { println(max(20, 10)) } fun max(a: Int, b: Int) = if (a > b) a else b 

Здесь у меня есть функция MAX. Теперь есть какая-либо разница между вышеприведенной реализацией и ниже реализации функции MAX, хотя оба дают одинаковый результат.

 fun max(a: Int, b: Int): Int?{ if(a > b) return a else return b } 

У вас есть три основных отличия между двумя функциями:

  1. Тип возврата отличается (как указывал воддан).
  2. Стиль тела отличается (это просто синтаксический сахар).
  3. Байт-код первой функции более эффективен.

Тип возврата

Kotlin имеет типы с нулевым значением и непустые типы . Int может использоваться в коде Kotlin как nullable, Int? , или non-null, Int и JVM отображаются в Integer и int соответственно.

Стиль тела

Функции Single-expression в Kotlin могут быть объявлены более сжато, используя тело выражения (в отличие от обычного тела блока). Следующие генерируют один и тот же байт-код:

Стиль тела выражения

 fun max(a: Int, b: Int) = if (a > b) a else b 

Тип возврата также может быть объявлен явно:

 fun max(a: Int, b: Int): Int = if (a > b) a else b 

Стиль кузова

 fun max(a: Int, b: Int): Int { return if (a > b) a else b } 

Байт-код

Байт-код первой функции загружает значение на основе условия, а затем возвращает загруженное значение, в то время как байт-код второй функции объявляет два блока, каждый из которых определяет его собственную нагрузку и возвращает, что приводит к более генерированному байт-коду.

  L0 LINENUMBER 8 L0 ILOAD 0 ILOAD 1 IF_ICMPLE L1 ILOAD 0 GOTO L2 L1 ILOAD 1 L2 IRETURN 

против

  L0 LINENUMBER 8 L0 ILOAD 0 ILOAD 1 IF_ICMPLE L1 L2 LINENUMBER 9 L2 ILOAD 0 IRETURN L3 L1 LINENUMBER 11 L1 ILOAD 1 IRETURN 

Единственное различие – это тип возврата: в первом случае это Int? , а Int? во втором случае.

Эта разница влияет на вас двумя способами:

1) Код, который использует max во втором случае, не может знать, возвращает ли он значение null или нет, поэтому он должен проверять его каждый раз (с помощью if-else или других методов)

2) Базовый код байта для 1-го случая (при условии, что вы используете бэкэнд JVM) использует примитивный int , а не вложенный в Integer . Это может значительно повысить производительность.