Функции расширения (extension function) позволяют добавить функционал к уже определенным типам. При этом типы могут быть определены где-то в другом месте, например, в стандартной библиотеке.
Функция расширения определяется следующим образом:
fun тип.имя_функции(параметры) : возвращаемый_тип{ тело функции }
По большому счету определение аналогично определению обычной функции за тем исключением, что после слова fun идет название типа, для которого определяется функция, и через точку название функции.
Определим пару функций расширения к стандартным типам Int и String:
fun main() { val hello: String = "hello world" println(hello.wordCount('l')) // 3 println(hello.wordCount('o')) // 2 println(4.square()) // 16 println(6.square()) // 36 } fun String.wordCount(c: Char) : Int{ var count = 0 for(n in this){ if(n == c) count++ } return count } fun Int.square(): Int{ return this * this }
Для типа Int определена функция возведения в квадрат. В каждой функции расширения через ключевое слово this мы можем ссылаться на текущий объект того типа, для которого создается функция. Например, в функции:
fun Int.square(): Int{ return this * this }
Через this обращаемся к тому объекту, для которого будет вызывться функция. И затем вы можем вызвать ее следующим образом:
4.square() // 16
Для типа String определена функция wordCount, которая подсчитывает, сколько встречается определенный символ в строке.
Следует учитывать, что в функциях расширения мы можем обращаться к любым общедоступным свойствам и методам объекта, однако не можем обращаться к свойствам и методам с модификаторами private и protected.
Также следует учитывать, что функции расширения не переопределяют функции, которые уже определены в классе. Если функция расширения имеет ту же сигнатуру, что и уже имеющаяся функция класса, то компилятор просто будет игнорировать подобную функцию расширения.