String Formatting in Kotlin

Kotlin offers excellent support for string formatting. Here are some examples of common string formatting tasks.

import kotlin.math.pow

data class Point(val x: Int, val y: Int)

fun main() {
    // Kotlin offers several printing functions designed to
    // format general Kotlin values. For example, this prints
    // an instance of our `Point` data class.
    val p = Point(1, 2)
    println("data class1: $p")

    // If the value is a data class, the `toString()` method
    // will include the class's property names by default.
    println("data class2: $p")

    // To print a representation similar to Kotlin source code,
    // you can use reflection or implement a custom toString() method.
    println("data class3: ${p.javaClass.simpleName}(x=${p.x}, y=${p.y})")

    // To print the type of a value, use `::class.java`.
    println("type: ${p::class.java}")

    // Formatting booleans is straightforward.
    println("bool: ${true}")

    // There are many options for formatting integers.
    // Use `toString()` for standard, base-10 formatting.
    println("int: ${123}")

    // This prints a binary representation.
    println("bin: ${14.toString(2)}")

    // This prints the character corresponding to the given integer.
    println("char: ${'!'}")

    // `toString(16)` provides hex encoding.
    println("hex: ${456.toString(16)}")

    // There are also several formatting options for floats.
    // For basic decimal formatting use `toString()`.
    println("float1: ${78.9}")

    // Use `%.2e` format specifier for scientific notation.
    println("float2: %.2e".format(123400000.0))
    println("float3: %.2E".format(123400000.0))

    // For basic string printing, use string interpolation.
    println("str1: \"string\"")

    // To print a representation of a string with quotes, use `"`
    println("str2: \"${"\""string"\""}\"")

    // As with integers seen earlier, we can use `map` and `joinToString`
    // to render the string in base-16, with two output characters per byte of input.
    println("str3: ${"hex this".map { it.code.toString(16).padStart(2, '0') }.joinToString("")}")

    // To print a representation of a reference, use `System.identityHashCode()`.
    println("reference: ${System.identityHashCode(p)}")

    // When formatting numbers you will often want to control the width and precision
    // of the resulting figure. Kotlin doesn't have a built-in Printf-style formatting,
    // but we can use String.format() or the `format` extension function.

    // To specify the width of an integer, use a number after the '%' in the format specifier.
    // By default, the result will be right-justified and padded with spaces.
    println("width1: |%6d|%6d|".format(12, 345))

    // You can also specify the width of printed floats, though usually you'll also want
    // to restrict the decimal precision at the same time with the width.precision syntax.
    println("width2: |%6.2f|%6.2f|".format(1.2, 3.45))

    // To left-justify, use the '-' flag.
    println("width3: |%-6.2f|%-6.2f|".format(1.2, 3.45))

    // You may also want to control width when formatting strings, especially to ensure
    // that they align in table-like output. For basic right-justified width:
    println("width4: |%6s|%6s|".format("foo", "b"))

    // To left-justify use the '-' flag as with numbers.
    println("width5: |%-6s|%-6s|".format("foo", "b"))

    // So far we've seen `println`, which prints the formatted string to the standard output.
    // You can use string interpolation or `String.format()` to create a formatted string
    // without printing it anywhere.
    val s = "sprintf: a ${String.format("%s", "string")}"
    println(s)

    // You can format+print to other output streams using `System.err.println()` for example.
    System.err.println("io: an ${String.format("%s", "error")}")
}

To run the program, save it as StringFormatting.kt and use kotlinc to compile it, then kotlin to run it:

$ kotlinc StringFormatting.kt -include-runtime -d StringFormatting.jar
$ kotlin -jar StringFormatting.jar
data class1: Point(x=1, y=2)
data class2: Point(x=1, y=2)
data class3: Point(x=1, y=2)
type: class Point
bool: true
int: 123
bin: 1110
char: !
hex: 1c8
float1: 78.9
float2: 1.23e+08
float3: 1.23E+08
str1: "string"
str2: ""string""
str3: 6865782074686973
reference: 1698276052
width1: |    12|   345|
width2: |  1.20|  3.45|
width3: |1.20  |3.45  |
width4: |   foo|     b|
width5: |foo   |b     |
sprintf: a string
io: an error

This Kotlin code demonstrates various string formatting techniques. While Kotlin doesn’t have a direct equivalent to Go’s fmt.Printf, it offers powerful string interpolation and the String.format() method for more complex formatting needs. The output closely resembles that of the original Go program, with slight differences due to language-specific features.