A large portion of the Kotlin standard library’s functionality is defined via extension functions and extension properties.
For example, take a look at the source code file Strings.kt (note: Strings, not String), by pressing the Shift key twice to open the Search Everywhere dialog and entering “Strings.kt”:
public inline fun CharSequence.trim(predicate: (Char) -> Boolean): CharSequence { var startIndex = 0 var endIndex = length - 1 var startFound = false while (startIndex <= endIndex) { val index = if (!startFound) startIndex else endIndex val match = predicate(this[index]) if (!startFound) { if (!match) startFound = true else startIndex += 1 } else { if (!match) break else endIndex -= 1 } } return subSequence(startIndex, endIndex + 1) }
Browse through this standard library file, and you will see that it consists of extensions to the String type. The excerpt above, for example, defines an extension function trim that is used to remove characters from a string.
Standard library files that contain extensions to a type are often named in this way, with an -s appended to the type name. If you look through the standard library files, you will notice other files matching this same naming convention: Sequences.kt, Ranges.kt, and Maps.kt are just some of the files that add functionality to the standard library through extensions to their corresponding type.
Heavy use of extension functions to define core API functionality is one of the ways that the Kotlin standard library keeps such a small footprint (~930k) but packs in so many features. Extensions use space efficiently because they can provide a feature for many types with one definition.
In this chapter, you have learned how extensions provide an alternative to sharing behavior with inheritance. In the next chapter you will delve into the fascinating world of functional programming.