Basic Syntax
Overview
This chapter provides detailed coverage of Kotlin's basic syntax rules, including identifiers, keywords, comments, package declarations, import statements, and other fundamental concepts. Mastering these syntax rules is essential for writing correct Kotlin code.
Identifiers and Naming Rules
Identifier Rules
kotlin
// Valid identifiers
val name = "Kotlin"
val userName = "john_doe"
val _privateVar = 42
val `special name` = "backticks allow spaces"
// Invalid identifiers (compilation errors)
// val 123name = "error" // Cannot start with a digit
// val class = "error" // Cannot use keywords
// val user-name = "error" // Cannot contain hyphensNaming Conventions
kotlin
// Class names: PascalCase
class UserManager
class DatabaseConnection
// Functions and variables: camelCase
fun calculateTotal() {}
val firstName = "John"
var currentUser = null
// Constants: UPPER_SNAKE_CASE
const val MAX_RETRY_COUNT = 3
const val API_BASE_URL = "https://api.example.com"
// Package names: lowercase, dot-separated
package com.example.myapp.utils
// File names: PascalCase or camelCase
// UserManager.kt
// databaseUtils.ktKeywords
Hard Keywords (Cannot Be Used as Identifiers)
kotlin
// Declaration keywords
class MyClass
fun myFunction()
val myValue = 10
var myVariable = 20
// Control flow keywords
if (true) { }
else { }
when (x) { }
for (i in 1..10) { }
while (true) { }
do { } while (false)
// Other keywords
import kotlin.collections.*
package com.example
return 42
throw Exception()
try { } catch (e: Exception) { }Soft Keywords (Have Special Meaning in Specific Contexts)
kotlin
// Special meaning in specific positions
class Person {
constructor(name: String) // constructor is a soft keyword
init { // init is a soft keyword
println("Initializing")
}
companion object { // companion and object are soft keywords
const val DEFAULT_NAME = "Unknown"
}
}Comments
Single-Line Comments
kotlin
// This is a single-line comment
val name = "Kotlin" // End-of-line comment
// TODO: Implement user authentication
// FIXME: Fix null pointer exception
// NOTE: This method needs optimizationMulti-Line Comments
kotlin
/*
* This is a multi-line comment
* It can span multiple lines
* Used for detailed explanations
*/
val version = "1.9"
/*
* Nested comments are also supported
* /* This is a nested comment */
* Outer comment continues
*/Documentation Comments (KDoc)
kotlin
/**
* Calculates the sum of two numbers
*
* @param a The first number
* @param b The second number
* @return The sum of the two numbers
* @throws IllegalArgumentException When parameters are invalid
* @since 1.0
* @author Kotlin Developer
*/
fun add(a: Int, b: Int): Int {
require(a >= 0 && b >= 0) { "Parameters must be non-negative" }
return a + b
}
/**
* User data class
*
* @property id Unique identifier for the user
* @property name User's name
* @property email User's email address
* @constructor Creates a new user instance
*/
data class User(
val id: Long,
val name: String,
val email: String
)Package Declaration and Imports
Package Declaration
kotlin
// Declare package name at the beginning of the file
package com.example.myapp.models
// Package names usually reflect directory structure
// src/main/kotlin/com/example/myapp/models/User.ktImport Statements
kotlin
// Import specific class
import java.util.Date
import kotlin.math.PI
// Import everything from a package
import kotlin.collections.*
// Import with alias (rename)
import java.util.Date as JavaDate
import kotlin.collections.List as KotlinList
// Import top-level functions
import kotlin.math.sqrt
import kotlin.math.pow
fun main() {
val date = JavaDate()
val list: KotlinList<String> = listOf("a", "b", "c")
val result = sqrt(16.0)
}Default Imports
kotlin
// These packages are automatically imported, no need for explicit imports
// kotlin.*
// kotlin.annotation.*
// kotlin.collections.*
// kotlin.comparisons.*
// kotlin.io.*
// kotlin.ranges.*
// kotlin.sequences.*
// kotlin.text.*
// JVM platform also auto-imports:
// java.lang.*
// kotlin.jvm.*Statements and Expressions
Statements vs Expressions
kotlin
fun main() {
// Statements: perform operations but don't return values
println("Hello") // Statement
var x = 10 // Statement
// Expressions: compute and return values
val sum = 5 + 3 // 5 + 3 is an expression
val max = if (x > 5) x else 5 // if is an expression
// when is also an expression
val grade = when (85) {
in 90..100 -> "A"
in 80..89 -> "B"
else -> "C"
}
}Block Expressions
kotlin
fun main() {
// The last expression in a block is the block's value
val result = {
val a = 10
val b = 20
a + b // This is the block's return value
}()
println("Result: $result") // Output: Result: 30
// Function bodies are also block expressions
fun calculate(): Int {
val x = 5
val y = 10
x * y // Return value, equivalent to return x * y
}
}Semicolons
kotlin
// Semicolons are optional in Kotlin
val name = "Kotlin"
val version = 1.9
// Multiple statements on the same line require semicolons
val a = 1; val b = 2; val c = 3
// Multiple statements on one line is generally not recommended
// Better approach:
val a = 1
val b = 2
val c = 3Literals
Numeric Literals
kotlin
fun main() {
// Integer literals
val decimal = 123
val long = 123L
val hexadecimal = 0x7B
val binary = 0b1111011
// Floating-point literals
val double = 123.45
val float = 123.45f
val scientific = 1.23e2 // 123.0
// Underscore separators (improve readability)
val million = 1_000_000
val creditCard = 1234_5678_9012_3456L
val bytes = 0xFF_EC_DE_5E
println("Decimal: $decimal")
println("Million: $million")
}Character Literals
kotlin
fun main() {
// Character literals
val char = 'A'
val digit = '9'
val space = ' '
// Escape characters
val tab = '\t'
val newline = '\n'
val backslash = '\\'
val quote = '\''
val doubleQuote = '\"'
// Unicode characters
val unicode = '\u0041' // 'A'
val emoji = '\u1F600' // 😀
println("Char: $char")
println("Unicode: $unicode")
}String Literals
kotlin
fun main() {
// Simple strings
val simple = "Hello, Kotlin!"
// Escaped strings
val escaped = "Line 1\nLine 2\tTabbed"
// Raw strings (triple quotes)
val raw = """
|This is a raw string
|It can contain newlines
|And "quotes" without escaping
|Backslashes \ are literal
""".trimMargin()
// String templates
val name = "Kotlin"
val version = 1.9
val template = "Welcome to $name version $version!"
val expression = "Length of name: ${name.length}"
println(template)
println(expression)
println(raw)
}Boolean Literals
kotlin
fun main() {
val isTrue = true
val isFalse = false
// Boolean operations
val and = true && false // false
val or = true || false // true
val not = !true // false
println("Boolean values: $isTrue, $isFalse")
}Operator Precedence
kotlin
fun main() {
// Arithmetic operator precedence (highest to lowest)
val result1 = 2 + 3 * 4 // 14 (not 20)
val result2 = (2 + 3) * 4 // 20
// Comparison operators
val comparison = 5 > 3 && 2 < 4 // true
// Assignment operator has lowest precedence
var x = 0
x += 2 * 3 // x = x + (2 * 3) = 6
println("Results: $result1, $result2, $comparison, $x")
}Type System Basics
Basic Types
kotlin
fun main() {
// Numeric types
val byte: Byte = 127
val short: Short = 32767
val int: Int = 2147483647
val long: Long = 9223372036854775807L
val float: Float = 3.14f
val double: Double = 3.14159265359
// Character type
val char: Char = 'K'
// Boolean type
val boolean: Boolean = true
// String type
val string: String = "Kotlin"
// Type checking
println("int is Int: ${int is Int}")
println("string is String: ${string is String}")
}Nullable Types
kotlin
fun main() {
// Non-nullable type
var name: String = "Kotlin"
// name = null // Compilation error
// Nullable type
var nullableName: String? = "Kotlin"
nullableName = null // Allowed
// Type check and cast
if (nullableName != null) {
println("Length: ${nullableName.length}") // Smart cast
}
// Safe cast
val obj: Any = "Hello"
val str: String? = obj as? String // Safe cast
println("Safe cast result: $str")
}Scope and Visibility
Local Scope
kotlin
fun main() {
val outerVar = "outer"
if (true) {
val innerVar = "inner"
println("Access outer: $outerVar") // Can access outer variable
println("Access inner: $innerVar")
}
// println(innerVar) // Compilation error: cannot access inner variable
// Block scope
run {
val blockVar = "block"
println("Block variable: $blockVar")
}
// println(blockVar) // Compilation error
}Function Scope
kotlin
// Top-level function
fun topLevelFunction() {
println("Top level function")
}
class MyClass {
// Member function
fun memberFunction() {
println("Member function")
}
// Local function
fun outerFunction() {
fun localFunction() {
println("Local function")
}
localFunction() // Call local function
}
}Coding Conventions
Indentation and Formatting
kotlin
// Use 4 spaces for indentation
class Person(
val name: String,
val age: Int,
val email: String
) {
fun introduce() {
println("Hello, I'm $name")
}
}
// Chain calls
val result = listOf(1, 2, 3, 4, 5)
.filter { it > 2 }
.map { it * 2 }
.sum()Naming Convention Summary
kotlin
// Package names: all lowercase, dot-separated
package com.example.myapp
// Classes and interfaces: PascalCase
class UserService
interface DatabaseRepository
// Functions and properties: camelCase
fun calculateTotal() {}
val userName = "john"
// Constants: UPPER_SNAKE_CASE
const val MAX_SIZE = 100
// Enum constants: UPPER_SNAKE_CASE
enum class Color {
RED, GREEN, BLUE
}Common Syntax Errors
1. Semicolon Usage Errors
kotlin
// Error: unnecessary semicolons
fun main() {
val name = "Kotlin"; // No semicolon needed
println(name); // No semicolon needed
}
// Correct
fun main() {
val name = "Kotlin"
println(name)
}2. Nullability Errors
kotlin
// Error: forgetting to handle nullability
fun processName(name: String?) {
// println(name.length) // Compilation error
}
// Correct: handle nullability
fun processName(name: String?) {
println(name?.length ?: 0)
}3. Type Inference Errors
kotlin
// Error: ambiguous type inference
// val list = emptyList() // Compilation error
// Correct: explicitly specify type
val list = emptyList<String>()
// Or
val list: List<String> = emptyList()Best Practices
- Follow Kotlin coding conventions
- Use meaningful variable and function names
- Use comments appropriately, especially KDoc
- Keep code concise and readable
- Leverage type inference but specify types when necessary
Next Steps
After mastering the basic syntax, let's learn about Kotlin's program structure, including classes, objects, packages, and other ways to organize code.
Next Chapter: Program Structure
Exercises
- Write a program demonstrating the use of all basic data types
- Create a function with complete KDoc documentation
- Practice different types of string literals and templates
- Write code demonstrating the effects of operator precedence
- Create a program to demonstrate scope rules