404 Not Found

404 Not Found


nginx

Kotlin Basic Syntax Explained

Kotlin's syntax philosophy: use expressions instead of statements wherever possible, and never write a line you don't need. This lets Alice write code that's 40% shorter than Java while expressing more.

1. What You'll Learn


2. A Developer's Real Story

(1) Pain Point: Mutable State Causes Concurrency Bugs

Alice used var to define a shared order counter in OrderProcessor. Under high concurrency, data races caused a 2% counting deviation — that's 20,000 miscounted orders at scale.

(2) Immutability-First Solution

KOTLIN
// BAD: mutable shared state
var orderCount = 0  // Race condition!

// GOOD: immutable + functional pipeline
val processedOrders = orders
    .filter { it.status == "CONFIRMED" }
    .also { println("Processed ${it.size} orders") }

Immutable data is naturally thread-safe. val is every Kotlin developer's first choice; var is a last resort.


3. val vs var: Immutability First

(1) Basic Syntax

KOTLIN
// val: read-only (immutable reference) - PREFERRED
val orderId = "ORD-001"         // Type inferred as String
val total: Double = 299.99      // Explicit type

// var: mutable (reassignable) - USE SPARINGLY
var status = "PENDING"          // Can be reassigned
status = "CONFIRMED"            // OK

// val does NOT mean the object is immutable
val items = mutableListOf<Order>()  // Reference is val, list is mutable
items.add(Order("ORD-002", 150.0, "NEW"))  // OK - modifying the list
// items = mutableListOf()  // ERROR - cannot reassign val

(2) val vs var Comparison

Dimension val var
Reassignable No Yes
Thread safety Reference immutable, naturally safe Needs synchronization
Recommendation Preferred Last resort
Java analog final Regular variable
Under the hood Read-only reference (object may be mutable) Mutable reference

4. String Templates

(1) Basic Templates

KOTLIN
val orderId = "ORD-001"
val total = 299.99

// Simple variable reference
println("Order: $orderId")

// Expression in template
println("Total: \$$total USD")
println("Tax: \$${total * 0.08} USD")

// Arbitrary expression with ${}
val items = listOf("Widget", "Gadget")
println("Item count: ${items.size}, First: ${items[0]}")

(2) Raw Strings (Multiline)

KOTLIN
val receipt = """
    |Order ID: ORD-001
    |Total: $299.99 USD
    |Status: CONFIRMED
""".trimMargin()

// Alternative: trimIndent
val json = """
    {
      "order_id": "ORD-001",
      "total": 299.99
    }
""".trimIndent()

(3) String Template Comparison

Feature Java Kotlin
Variable reference "Order " + id "Order $id"
Expression "Tax: " + (t * 0.08) "Tax: ${t * 0.08}"
Multiline No native support """ ... """
Indent handling Manual trimMargin() / trimIndent()

5. when Expression

when is switch's comprehensive upgrade — it's an expression with a return value that can match types, ranges, and arbitrary conditions.

(1) Basic Usage

KOTLIN
// when as expression (must be exhaustive)
val status = "CONFIRMED"
val label = when (status) {
    "PENDING" -> "Waiting for payment"
    "CONFIRMED" -> "Payment received"
    "SHIPPED" -> "In transit"
    "CANCELLED" -> "Order cancelled"
    else -> "Unknown status"
}

(2) Advanced Matching

KOTLIN
// Multiple values
when (status) {
    "PENDING", "NEW" -> processNewOrder()
    in listOf("CONFIRMED", "PAID") -> shipOrder()
    else -> handleOther()
}

// Range matching
val quantity = 150
when (quantity) {
    in 1..10 -> println("Small order")
    in 11..100 -> println("Medium order")
    in 101..1_000 -> println("Large order")
    else -> println("Bulk order")
}

// Type matching
fun describe(obj: Any): String = when (obj) {
    is String -> "String of length ${obj.length}"
    is Int -> "Integer: $obj"
    is List<*> -> "List with ${obj.size} elements"
    else -> "Unknown type"
}

(3) when Decision Tree

100%
flowchart LR
    A[when status] --> B["PENDING, NEW"]
    A --> C["CONFIRMED, PAID"]
    A --> D["SHIPPED"]
    A --> E["CANCELLED"]
    A --> F[else]
    B --> B1[processNewOrder]
    C --> C1[shipOrder]
    D --> D1[trackShipment]
    E --> E1[refundOrder]
    F --> F1[handleOther]

(4) when vs switch

Dimension Java switch Kotlin when
Return value Statement, no return Expression, returns value
Multi-value match Requires fall-through "A", "B" comma-separated
Range match Not available in 1..100
Type match Not available is String
Guard condition Not available x > 0 arbitrary
Exhaustiveness check None Compiler-enforced (expression mode)

6. Ranges and Iteration

(1) Range Operators

KOTLIN
// Closed range: includes both ends
for (i in 1..5) print("$i ")  // 1 2 3 4 5

// Half-open range: excludes end
for (i in 1 until 5) print("$i ")  // 1 2 3 4

// Step
for (i in 1..10 step 2) print("$i ")  // 1 3 5 7 9

// DownTo
for (i in 5 downTo 1) print("$i ")  // 5 4 3 2 1

// Char range
for (c in 'A'..'E') print("$c ")  // A B C D E

(2) Collection Iteration

KOTLIN
val orders = listOf(
    Order("ORD-001", 299.99),
    Order("ORD-002", 1_500.00),
    Order("ORD-003", 45.50)
)

// Iterate with index
for ((index, order) in orders.withIndex()) {
    println("[$index] ${order.id}: \$${order.total} USD")
}

// Iterate map
val statusMap = mapOf("ORD-001" to "SHIPPED", "ORD-002" to "PENDING")
for ((id, status) in statusMap) {
    println("$id -> $status")
}

(3) Range Operator Quick Reference

Operator Meaning Example Result
.. Closed range 1..5 1,2,3,4,5
until Half-open range 1 until 5 1,2,3,4
step Step size 1..10 step 3 1,4,7,10
downTo Decreasing 5 downTo 1 5,4,3,2,1
in Membership check 3 in 1..5 true

7. Expression-Body Functions and Idioms

(1) Expression-Body Functions

KOTLIN
// Block body
fun calculateTax(total: Double): Double {
    return total * 0.08
}

// Expression body (more concise)
fun calculateTax(total: Double): Double = total * 0.08

// Type inference with expression body
fun calculateTax(total: Double) = total * 0.08

(2) Kotlin Idioms

KOTLIN
// 1. Semicolons are optional
val x = 1  // No semicolon needed

// 2. Trailing lambda convention
orders.filter { it.total > 1_000 }  // lambda outside parens

// 3. It keyword for single-parameter lambda
orders.map { it.id }  // 'it' = implicit parameter

// 4. String template over concatenation
val msg = "Order $orderId confirmed"  // Not "Order " + orderId + " confirmed"

// 5. Expression body for simple functions
fun isHighValue(order: Order) = order.total > 10_000

(3) Java vs Kotlin Idiom Comparison

Idiom Java Kotlin
Semicolons Required Optional
String concat + operator $ template
Simple functions Block body Expression body
Lambda placement Inside parens Trailing outside parens
Single-parameter lambda Named parameter it keyword

8. Complete Example: OrderProcessor Order Routing

KOTLIN
// ============================================
// OrderProcessor - Order Routing Engine
// Feature: Route orders based on status and value
// ============================================

data class Order(val id: String, val total: Double, val status: String)

fun routeOrder(order: Order): String = when {
    order.status == "CANCELLED" -> "REFUND_QUEUE"
    order.total > 10_000 -> "VIP_PIPELINE"
    order.total > 1_000 -> "PRIORITY_PIPELINE"
    order.status == "CONFIRMED" -> "STANDARD_PIPELINE"
    order.status in listOf("PENDING", "NEW") -> "WAITING_QUEUE"
    else -> "MANUAL_REVIEW"
}

fun processBatch(orders: List<Order>) {
    for ((index, order) in orders.withIndex()) {
        val pipeline = routeOrder(order)
        val priority = when (pipeline) {
            "VIP_PIPELINE" -> "CRITICAL"
            "PRIORITY_PIPELINE" -> "HIGH"
            "STANDARD_PIPELINE" -> "NORMAL"
            else -> "LOW"
        }
        println("[${index + 1}] ${order.id} -> $pipeline (Priority: $priority)")
    }
}

fun main() {
    val orders = listOf(
        Order("ORD-001", 299.99, "CONFIRMED"),
        Order("ORD-002", 15_000.00, "CONFIRMED"),
        Order("ORD-003", 2_500.00, "PENDING"),
        Order("ORD-004", 45.50, "CANCELLED"),
        Order("ORD-005", 750.00, "NEW")
    )

    println("=== Order Routing Report ===")
    processBatch(orders)

    // Summary with functional pipeline
    val pipelineCounts = orders
        .map { routeOrder(it) }
        .groupingBy { it }
        .eachCount()

    println("\n=== Pipeline Distribution ===")
    for ((pipeline, count) in pipelineCounts) {
        println("  $pipeline: $count orders")
    }
}

Output:

TEXT
=== Order Routing Report ===
[1] ORD-001 -> STANDARD_PIPELINE (Priority: NORMAL)
[2] ORD-002 -> VIP_PIPELINE (Priority: CRITICAL)
[3] ORD-003 -> PRIORITY_PIPELINE (Priority: HIGH)
[4] ORD-004 -> REFUND_QUEUE (Priority: LOW)
[5] ORD-005 -> WAITING_QUEUE (Priority: LOW)

=== Pipeline Distribution ===
  STANDARD_PIPELINE: 1 orders
  VIP_PIPELINE: 1 orders
  PRIORITY_PIPELINE: 1 orders
  REFUND_QUEUE: 1 orders
  WAITING_QUEUE: 1 orders

❓ FAQ

Q Can I modify the contents of a val collection?
A Yes. val only guarantees the reference is immutable — the collection contents can still change. For truly immutable collections, use listOf() instead of mutableListOf().
Q Does when always require else?
A When when is used as an expression, the compiler requires exhaustiveness — you must cover all branches or add else. When used as a statement, else is optional.
Q Are 1..5 and 1 until 6 the same?
A Same result, different semantics. 1..5 means "from 1 to 5 inclusive", 1 until 6 means "from 1 up to (but not including) 6". When iterating list indices, until is more common.
Q When should I use expression-body functions?
A Use expression bodies when the function is a single expression. Use block bodies for anything with 2+ lines of logic. Readability is the top priority.
Q What's the difference between $var and ${expr} in string templates?
A $var can only reference simple variable names; ${expr} can contain any expression, like ${items.size} or ${total * 0.08}.
Q Can when match floating-point ranges?
A Technically yes, but floating-point precision issues can cause unexpected results. Prefer integer ranges or explicit comparisons.

▶ Example: val vs var

KOTLIN
val name = "Alice"  // immutable
var age = 30        // mutable
age = 31            // OK
// name = "Bob"     // compile error

Output:

TEXT
Compiles; reassigning name fails

▶ Example: when Expression

KOTLIN
val score = 85
val grade = when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    else -> "C"
}
println(grade)

Output:

TEXT
B

▶ Example: for Loop

KOTLIN
for (i in 1..3) println(i)
for (s in listOf("a", "b")) println(s)

Output:

TEXT
1
2
3
a
b

📖 Summary


📝 Exercises

  1. Beginner (⭐) : Write a function using val and string templates that outputs an order summary "ORD-001: $299.99 USD (CONFIRMED)". Hint: val id = "ORD-001", val total = 299.99
  2. Intermediate (⭐⭐) : Implement a discount calculator with when: > 10,000 → 20% off, > 5,000 → 10% off, otherwise full price. Hint: when {} guard conditions
  3. Challenge (⭐⭐⭐) : Implement a progressive tax calculator using ranges and when. Different income brackets apply different tax rates. Hint: when { income in range -> ... }

← Previous | Next →

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏