An extension property adds property-style access to an existing type without modifying its source or storing state in its instances. It resembles a regular property with a receiver type, but it must define custom accessors because no backing field exists. section 3.3.5 section 3.7
A read-only extension property computes the last character of a String while preserving property syntax. section 3.3.5
Use extension properties with these constraints and conventions:
- Define a getter explicitly; initializers and default accessors are unavailable because the extension has no backing field. section 3.3.5
- Declare a mutable extension property when the receiver already exposes mutable state, as with StringBuilder. section 3.3.5
- Call extensions with ordinary property syntax in Kotlin, but invoke generated getters and setters explicitly from Java. section 3.3.5
- Use extensions on primitive receivers to create concise domain-specific values such as days, hours, and fortnights. section 13.4.2
Mutable last-character access
var StringBuilder.lastChar: Char get() = this.get(length - 1) set(value) { this.setCharAt(length - 1, value) } fun main() { val sb = StringBuilder("Kotlin?") println(sb.lastChar) sb.lastChar = '!' println(sb) } section 3.3.5
Listing 13.21 Defining a date manipulation DSL
import kotlin.time.DurationUnit
val Int.days: Duration
get() = this.toDuration(DurationUnit.DAYS) #1
val Int.hours: Duration
get() = this.toDuration(DurationUnit.HOURS) #2
Primitive receivers can expose readable measurement syntax; Int.days and Int.hours convert numeric values into Duration values. section 13.4.2
Generic accessors can also be inline and reified: a canonical extension property uses T::class.java to expose the canonical Java class name through property syntax. section 11.2.4
