Skip to main content

Variables & Constants

Definition

In Swift gibt es zwei Arten, Werte zu speichern:

  • Constants (Konstanten) mit let - Werte können nach der Zuweisung nicht mehr geändert werden
  • Variables (Variablen) mit var - Werte können beliebig oft geändert werden

Best Practice: Verwende immer let, außer du musst den Wert wirklich ändern.

Basic Syntax

// Konstante mit let
let name = "Max"
let age = 25
let pi = 3.14159

// Variable mit var
var score = 0
var isLoggedIn = false
var currentLevel = 1

Typ-Angabe

// Explizite Typ-Angabe
let name: String = "Max"
let age: Int = 25
let height: Double = 1.85
let isActive: Bool = true

// Type Inference (empfohlen)
let name = "Max" // Swift erkennt: String
let age = 25 // Swift erkennt: Int
let height = 1.85 // Swift erkennt: Double
let isActive = true // Swift erkennt: Bool

Constants (let)

// Einmal zuweisen
let username = "john_doe"
let maxAttempts = 3
let apiKey = "abc123xyz"

// Kann nicht geändert werden
// username = "jane_doe" // ❌ Error!

// Wert kann später zugewiesen werden
let greeting: String
if isGerman {
greeting = "Hallo"
} else {
greeting = "Hello"
}
// greeting = "Hi" // ❌ Error! Bereits zugewiesen

// Konstanten in Funktionen
func calculateArea(width: Double, height: Double) -> Double {
let area = width * height // Wird nie geändert
return area
}

Variables (var)

// Wert kann geändert werden
var counter = 0
counter = 1
counter = 2

var message = "Hello"
message = "Hi"
message = "Hey there!"

// In Schleifen
var sum = 0
for number in 1...10 {
sum += number // sum wird kontinuierlich erhöht
}

// Mit Bedingungen
var status = "pending"
if isCompleted {
status = "completed"
} else {
status = "failed"
}

Grundlegende Datentypen

Integer (Int)

let smallNumber = 5
let bigNumber = 1_000_000 // Unterstriche für Lesbarkeit

// Positive und negative Zahlen
let positive = 42
let negative = -42
let zero = 0

// Min/Max Werte
let minInt = Int.min // -9223372036854775808 (64-bit)
let maxInt = Int.max // 9223372036854775807 (64-bit)

Double und Float

// Double (Standard für Dezimalzahlen)
let pi = 3.14159
let price = 19.99
let temperature = -5.5

// Float (weniger genau, braucht explizite Angabe)
let piFloat: Float = 3.14159
let smallDecimal: Float = 0.1

// Wissenschaftliche Notation
let billion = 1e9 // 1_000_000_000
let millionth = 1e-6 // 0.000001

String

// Einfache Strings
let firstName = "Max"
let lastName = "Mustermann"

// String Interpolation
let fullName = "\(firstName) \(lastName)"
let message = "Mein Name ist \(fullName)"

// Mehrzeilige Strings
let multiline = """
Zeile 1
Zeile 2
Zeile 3
"""

// Leerer String
let empty = ""
let alsoEmpty = String()

Boolean

let isActive = true
let isCompleted = false

// In Bedingungen
let hasPermission = true
if hasPermission {
print("Zugriff erlaubt")
}

// Logische Operationen
let isValid = true
let isEnabled = false
let result = isValid && isEnabled // false
let either = isValid || isEnabled // true
let opposite = !isValid // false

Naming Conventions

// ✅ Gute Namen - beschreibend und camelCase
let userName = "john_doe"
let maxRetryCount = 3
let isLoggedIn = true
let backgroundColor = UIColor.white

// ❌ Schlechte Namen
let x = "john_doe" // Zu kurz
let UserName = "john_doe" // Großbuchstabe am Anfang
let user_name = "john_doe" // snake_case statt camelCase
let n = 3 // Nicht beschreibend

Multiple Variables

// Mehrere Variables auf einmal
var x = 0, y = 0, z = 0

// Mit Typ-Angabe
var red: Int, green: Int, blue: Int

// Tuple Destructuring
let (firstName, lastName) = ("Max", "Mustermann")
print(firstName) // "Max"
print(lastName) // "Mustermann"

let (x, y, z) = (1, 2, 3)

Optionals

// Optional Variable - kann nil sein
var optionalName: String? = "Max"
optionalName = nil // Erlaubt

// Non-Optional Variable - kann NICHT nil sein
var requiredName: String = "Max"
// requiredName = nil // ❌ Error!

// Optional mit Wert
var age: Int? = 25
if let unwrappedAge = age {
print("Age is \(unwrappedAge)")
}

// Optional mit nil
var height: Double? = nil
print(height ?? 0.0) // 0.0 (default value)

Computed Properties

// In Struct oder Class
struct Circle {
var radius: Double

// Computed property (keine Speicherung)
var diameter: Double {
return radius * 2
}

var area: Double {
return Double.pi * radius * radius
}
}

let circle = Circle(radius: 5)
print(circle.diameter) // 10.0
print(circle.area) // 78.53981633974483

Property Observers

// willSet und didSet
struct Counter {
var count: Int = 0 {
willSet {
print("Will set to \(newValue)")
}
didSet {
print("Changed from \(oldValue) to \(count)")
}
}
}

var counter = Counter()
counter.count = 5
// Output:
// Will set to 5
// Changed from 0 to 5

Lazy Variables

class DataManager {
// Wird erst erstellt, wenn es gebraucht wird
lazy var data: [String] = {
print("Loading data...")
return ["Item 1", "Item 2", "Item 3"]
}()

lazy var expensiveComputation: Int = {
print("Computing...")
var sum = 0
for i in 1...1000 {
sum += i
}
return sum
}()
}

let manager = DataManager()
// "Loading data..." wird NICHT ausgegeben
print("Manager created")

// Erst hier wird data initialisiert
print(manager.data)
// Output:
// Manager created
// Loading data...
// ["Item 1", "Item 2", "Item 3"]

Static Variables

struct AppConfig {
static let appName = "MyApp"
static let version = "1.0.0"
static var userCount = 0
}

// Zugriff ohne Instanz
print(AppConfig.appName) // "MyApp"
print(AppConfig.version) // "1.0.0"

AppConfig.userCount = 100
print(AppConfig.userCount) // 100

SwiftUI Property Wrappers

// @State - für lokale View-State
struct ContentView: View {
@State private var counter = 0
@State private var isOn = false
@State private var text = ""

var body: some View {
VStack {
Text("Counter: \(counter)")
Button("Increment") {
counter += 1
}
}
}
}

// @Binding - für geteilten State
struct ChildView: View {
@Binding var isOn: Bool

var body: some View {
Toggle("Switch", isOn: $isOn)
}
}

// @ObservedObject - für externe Objekte
class ViewModel: ObservableObject {
@Published var count = 0
@Published var name = ""
}

struct MyView: View {
@ObservedObject var viewModel = ViewModel()

var body: some View {
Text("\(viewModel.count)")
}
}

Praktische Beispiele

Counter App

struct CounterView: View {
@State private var count = 0

var body: some View {
VStack {
Text("Count: \(count)")
.font(.largeTitle)

HStack {
Button("−") {
count -= 1
}

Button("Reset") {
count = 0
}

Button("+") {
count += 1
}
}
}
}
}

Form mit Validation

struct LoginView: View {
@State private var username = ""
@State private var password = ""

private var isValid: Bool {
!username.isEmpty && password.count >= 6
}

var body: some View {
Form {
TextField("Username", text: $username)
SecureField("Password", text: $password)

Button("Login") {
login()
}
.disabled(!isValid)
}
}

func login() {
print("Logging in as \(username)")
}
}

Settings

struct SettingsView: View {
@State private var notificationsEnabled = true
@State private var darkModeEnabled = false
@State private var fontSize: Double = 16

var body: some View {
Form {
Section("Notifications") {
Toggle("Enable Notifications", isOn: $notificationsEnabled)
}

Section("Appearance") {
Toggle("Dark Mode", isOn: $darkModeEnabled)
Slider(value: $fontSize, in: 12...24)
Text("Font Size: \(Int(fontSize))")
}
}
}
}

Best Practices

  1. Verwende let standardmäßig: Nur var wenn Wert sich ändert
// ✅ Gut
let name = "Max"
let age = 25

// ❌ Unnötig
var name = "Max" // Wird nie geändert
var age = 25 // Wird nie geändert
  1. Beschreibende Namen: Selbsterklärend statt kurz
// ✅ Gut
let maximumRetryAttempts = 3
let isUserLoggedIn = true

// ❌ Schlecht
let max = 3
let flag = true
  1. Richtige Datentypen: Passender Typ für den Anwendungsfall
// ✅ Gut
let price: Double = 19.99 // Geld: Double
let count: Int = 5 // Anzahl: Int
let name: String = "Max" // Text: String

// ❌ Schlecht
let price: Int = 20 // Verliert Cents
let count: Double = 5.0 // Unnötig präzise
  1. Optionals nur wenn nötig: Nicht jeder Wert braucht Optional
// ✅ Gut - Optional wenn Wert fehlen kann
var middleName: String? = nil

// ❌ Schlecht - Nicht nötig
var firstName: String? = "Max" // firstName ist immer vorhanden

Common Use Cases

  • State Management: @State in SwiftUI Views
  • Configuration: Constants für App-Settings
  • Counters: Scores, Indices, Zählvariablen
  • User Input: TextField, Form Values
  • Flags: Boolean für Status (isLoading, isVisible)
  • Collections: Arrays, Dictionaries (var für mutable)
  • Optionals: Umgang mit fehlenden Werten
  • Property Wrappers: @State, @Binding, @Published
  • Type Inference: Automatische Typ-Erkennung
  • Data Types: String, Int, Double, Bool