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
- Verwende
letstandardmäßig: Nurvarwenn 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
- Beschreibende Namen: Selbsterklärend statt kurz
// ✅ Gut
let maximumRetryAttempts = 3
let isUserLoggedIn = true
// ❌ Schlecht
let max = 3
let flag = true
- 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
- 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)
Related Topics
- Optionals: Umgang mit fehlenden Werten
- Property Wrappers: @State, @Binding, @Published
- Type Inference: Automatische Typ-Erkennung
- Data Types: String, Int, Double, Bool