Kotlin Basic Syntax and Data Types: val vs var, Null Safety, Type Inference & More

1. What is the Basic Structure of a Kotlin Program?

A Kotlin program consists of a package declaration, imports, and a main function as the entry point. It uses .kt files and compiles to JVM bytecode, JavaScript, or native code.

Key Components:

Syntax:

package com.example
import kotlin.math.sqrt

fun main() {
    println("Hello, Kotlin!")
}

Use Case: Simple console applications or building blocks for Android/iOS apps.

Example: Basic Program Structure

package com.example

import kotlin.math.sqrt

// Top-level function
fun calculateSquare(n: Int): Int = n * n

fun main() {
    val message = "Hello, Kotlin!"
    println(message)
    
    val number = 5
    val square = calculateSquare(number)
    println("Square of $number is $square")
}
Output: Hello, Kotlin! Square of 5 is 25

Note: package defines namespace; import brings in sqrt (unused here for demo). fun defines functions; main is the entry point. Compile and run with kotlinc HelloKotlin.kt -include-runtime -d HelloKotlin.jar and java -jar HelloKotlin.jar.

2. What are val and var in Kotlin?

val: Immutable variable (constant), cannot be reassigned after initialization. Similar to final in Java.

var: Mutable variable, can be reassigned. Similar to regular variables in Java.

Syntax:

val immutable = 10  // Cannot reassign
var mutable = "Hello"  // Can reassign

Use Case: val for constants (e.g., PI); var for changing values (e.g., counters).

Example: val and var

fun main() {
    val pi = 3.14  // Immutable
    println("Pi: $pi")
    
    var counter = 0  // Mutable
    counter++
    println("Counter: $counter")
    
    // pi = 3.14159  // Error: Val cannot be reassigned
    counter = 10
    println("Updated counter: $counter")
}
Output: Pi: 3.14 Counter: 1 Updated counter: 10

Note: val pi prevents reassignment; var counter allows it. Kotlin's type inference omits types (e.g., Double, Int).

3. What are the Basic Data Types in Kotlin?

Numeric:

Boolean: True/false (e.g., true, false).

Char: Single character (e.g., 'A').

String: Sequence of characters (e.g., "Hello").

Use Case: Storing numbers, text, or flags for calculations or display.

Example: Basic Data Types

fun main() {
    val myInt: Int = 42
    val myDouble: Double = 3.14
    val myFloat: Float = 3.14f
    val myBoolean: Boolean = true
    val myChar: Char = 'A'
    val myString: String = "Hello, Kotlin!"

    println("Int: $myInt")
    println("Double: $myDouble")
    println("Float: $myFloat")
    println("Boolean: $myBoolean")
    println("Char: $myChar")
    println("String: $myString")
}
Output: Int: 42 Double: 3.14 Float: 3.14 Boolean: true Char: A String: Hello, Kotlin!

Note: Explicit typing (: Type) is optional; Kotlin infers types. Strings use double quotes; chars use single quotes.

4. What is Type Inference and Explicit Typing in Kotlin?

Type Inference: Kotlin automatically deduces variable types from context (e.g., val x = 42 infers Int).

Explicit Typing: Manually specifying types (e.g., val x: Int = 42).

Benefits: Inference reduces boilerplate; explicit typing improves readability for complex types.

Use Case: Inference for simple variables; explicit for function parameters or complex returns.

Example: Type Inference and Explicit Typing

fun main() {
    // Type inference
    val inferredInt = 42  // Inferred as Int
    val inferredString = "Hello"  // Inferred as String
    
    // Explicit typing
    val explicitInt: Int = 42
    val explicitString: String = "Hello"
    
    println("Inferred Int: $inferredInt, Type: ${inferredInt::class.simpleName}")
    println("Explicit Int: $explicitInt, Type: ${explicitInt::class.simpleName}")
}
Output: Inferred Int: 42, Type: Int Explicit Int: 42, Type: Int

Note: Inference works for primitives; explicit typing is useful for clarity or generics.

5. What are Nullable Types and Null Safety in Kotlin?

Nullable Types: Allow variables to hold null (e.g., String?).

Non-Nullable Types: Cannot hold null (default, e.g., String).

Null Safety: Kotlin's type system prevents null reference exceptions at compile time.

Use Case: Handling optional data safely.

Example: Nullable Types and Null Safety

fun main() {
    val nonNullable: String = "Hello"
    // nonNullable = null  // Error: Type mismatch
    
    var nullable: String? = null
    nullable = "World"
    
    // Safe call
    val length = nullable?.length ?: 0
    println("Length: $length")
    
    // Force unwrap (dangerous)
    // val unsafe = nullable!!  // Throws NPE if null
    
    // Elvis operator
    val message = nullable ?: "Default message"
    println("Message: $message")
}
Output: Length: 0 Message: Default message

Note: ? allows null; ?. and ?: handle it safely. !! is risky; prefer safe alternatives.

6. Comprehensive Example Combining All Concepts

This example combines program structure, variables, data types, type inference, and null safety in a single Kotlin program.

// Comprehensive Kotlin program
package com.example

// Class with init and variables
class Employee(val name: String, var salary: Double, val deptId: Int) {
    // Instance variable
    private var bonus: Double = 0.0
    
    // Method
    fun calculateBonus(percentage: Double): Double {
        bonus = salary * (percentage / 100)
        return bonus
    }
    
    fun displayInfo(): String {
        return "Employee: $name, Salary: $$salary, Bonus: $$bonus, Dept: $deptId"
    }
}

fun main() {
    // Type inference
    val inferredInt = 42  // Inferred as Int
    val inferredString = "Hello"  // Inferred as String
    
    // Explicit typing
    val explicitInt: Int = 42
    val explicitDouble: Double = 3.14
    val explicitBoolean: Boolean = true
    val explicitChar: Char = 'A'
    
    // Nullable types
    val nonNullable: String = "Kotlin"
    val nullable: String? = null
    
    // Safe call and Elvis
    val length = nullable?.length ?: 0
    
    // Variables: val and var
    val immutable = "Constant"
    var mutable = 10
    mutable += 5
    
    // Create object
    val emp = Employee("Krishna", 60000.0, 1)
    emp.calculateBonus(10.0)
    println(emp.displayInfo())
    println("Inferred Int: $inferredInt")
    println("Length of nullable: $length")
    println("Updated mutable: $mutable")
}
Output: Employee: Krishna, Salary: $60000.0, Bonus: $6000.0, Dept: 1 Inferred Int: 42 Length of nullable: 0 Updated mutable: 15

Description:

7. Common Mistakes and Best Practices

Common Mistakes:

Best Practices: