{"id":2724,"date":"2026-02-05T11:38:13","date_gmt":"2026-02-05T11:38:13","guid":{"rendered":"https:\/\/demo.materiamedica.net\/demo6\/?p=2724"},"modified":"2026-02-05T11:38:39","modified_gmt":"2026-02-05T11:38:39","slug":"chapter-69-swift-mutability-let-vs-var","status":"publish","type":"post","link":"https:\/\/demo.materiamedica.net\/demo6\/chapter-69-swift-mutability-let-vs-var\/","title":{"rendered":"Chapter 69: Swift Mutability (let vs var)"},"content":{"rendered":"<h3 dir=\"auto\">1. The Core Idea \u2013 What \u201cmutability\u201d really means<\/h3>\n<p dir=\"auto\">In Swift, <strong>mutability<\/strong> = \u201ccan this thing be changed after I create it?\u201d<\/p>\n<p dir=\"auto\">Swift gives you <strong>two keywords<\/strong> to control mutability:<\/p>\n<ul dir=\"auto\">\n<li><strong>let<\/strong> = <strong>constant<\/strong> \u2192 the value <strong>cannot be changed<\/strong> after creation (immutable = \u201cI promise this will never change\u201d)<\/li>\n<li><strong>var<\/strong> = <strong>variable<\/strong> \u2192 the value <strong>can be changed<\/strong> later (mutable = \u201cthis is allowed to change\u201d)<\/li>\n<\/ul>\n<p dir=\"auto\"><strong>Very important mindset shift<\/strong> (this is what separates beginners from good Swift developers):<\/p>\n<blockquote dir=\"auto\">\n<p dir=\"auto\">In modern Swift, the <strong>default recommendation<\/strong> is: <strong>Use let by default \u2014 everywhere.<\/strong> <strong>Use var only when you are sure the value will actually need to change.<\/strong><\/p>\n<\/blockquote>\n<p dir=\"auto\">This is <strong>not<\/strong> just a style rule \u2014 it is one of the strongest safety features of Swift.<\/p>\n<h3 dir=\"auto\">2. The simplest examples \u2013 feel the difference<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>\/\/ let = constant = cannot be reassigned\r\nlet name = \"Priya\"\r\nname = \"Sneha\"      \/\/ \u274c Compile error: Cannot assign to value: 'name' is a 'let' constant\r\n\r\n\/\/ var = variable = can be reassigned\r\nvar score = 100\r\nscore = 150         \/\/ \u2705 OK\r\nscore += 50         \/\/ \u2705 OK, now 200\r\nscore = 0           \/\/ \u2705 OK<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let temperature = 32.5\r\n\/\/ temperature = 33.0   \/\/ \u274c cannot change\r\n\r\nvar currentTemperature = 32.5\r\ncurrentTemperature = 33.2   \/\/ \u2705 OK<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">3. The most important rule used by experienced developers<\/h3>\n<p dir=\"auto\"><strong>Ask yourself this question every single time you declare something:<\/strong><\/p>\n<blockquote dir=\"auto\">\n<p dir=\"auto\">\u201cWill this value ever need to be <strong>completely replaced<\/strong> with a different value later in this scope?\u201d<\/p>\n<\/blockquote>\n<ul dir=\"auto\">\n<li>If the answer is <strong>\u201cNo\u201d<\/strong> or <strong>\u201cProbably not\u201d<\/strong> \u2192 use let<\/li>\n<li>If the answer is <strong>\u201cYes, definitely\u201d<\/strong> \u2192 use var<\/li>\n<\/ul>\n<p dir=\"auto\">This single question catches ~80\u201390% of cases correctly.<\/p>\n<h3 dir=\"auto\">4. Real-life examples \u2013 how good developers actually choose let vs var<\/h3>\n<h4 dir=\"auto\">Example 1 \u2013 User profile (very common)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>struct User {\r\n    let id: UUID                \/\/ never changes\r\n    let createdAt: Date         \/\/ never changes\r\n    let email: String           \/\/ usually never changes\r\n    var displayName: String     \/\/ user can change it\r\n    var bio: String?            \/\/ user can change it\r\n    var profilePhotoURL: URL?   \/\/ user can change it\r\n    var isPremium: Bool         \/\/ can change over time\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">\u2192 <strong>Identity<\/strong> fields \u2192 let \u2192 <strong>Editable<\/strong> fields \u2192 var<\/p>\n<h4 dir=\"auto\">Example 2 \u2013 Settings screen<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>struct AppSettings {\r\n    let appVersion = \"2.3.1\"                \/\/ never changes in this run\r\n    let apiBaseURL = URL(string: \"https:\/\/api.example.com\/v2\")!\r\n    \r\n    var theme: Theme = .system              \/\/ user can change\r\n    var fontSize: CGFloat = 16              \/\/ user can change\r\n    var notificationsEnabled = true         \/\/ user can change\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">\u2192 Fixed constants \u2192 let \u2192 User preferences \u2192 var<\/p>\n<h4 dir=\"auto\">Example 3 \u2013 Game state (very typical)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>class GameSession {\r\n    let playerID: UUID              \/\/ fixed\r\n    let startTime: Date             \/\/ fixed\r\n    \r\n    var currentScore = 0            \/\/ changes a lot\r\n    var livesRemaining = 3          \/\/ decreases\r\n    var level = 1                   \/\/ increases\r\n    var isGameOver = false          \/\/ changes once\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">\u2192 Identity &amp; creation data \u2192 let \u2192 State that changes during gameplay \u2192 var<\/p>\n<h4 dir=\"auto\">Example 4 \u2013 Function parameters &amp; local variables<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>func calculateTotalPrice(items: [CartItem], taxRate: Double) -&gt; Double {\r\n    let subtotal = items.reduce(0.0) { $0 + $1.price * Double($1.quantity) }\r\n    \r\n    \/\/ subtotal is never reassigned \u2192 let\r\n    let taxAmount = subtotal * taxRate\r\n    \r\n    \/\/ final total is never reassigned \u2192 let\r\n    let finalTotal = subtotal + taxAmount\r\n    \r\n    return finalTotal\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Golden habit<\/strong>: Inside functions, <strong>default to let<\/strong> for every local variable unless you actually reassign it.<\/p>\n<h3 dir=\"auto\">5. Very Common Beginner Mistakes &amp; Correct Habits<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Mistake<\/th>\n<th data-col-size=\"md\">Wrong \/ Risky code<\/th>\n<th data-col-size=\"md\">Correct \/ Better habit<\/th>\n<th data-col-size=\"xl\">Why?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">Using var everywhere \u201cjust in case\u201d<\/td>\n<td data-col-size=\"md\">var name = &#8220;Priya&#8221;; var age = 24;<\/td>\n<td data-col-size=\"md\">Default to let unless you really reassign<\/td>\n<td data-col-size=\"xl\">let prevents accidental changes + better safety<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Reassigning constants by mistake<\/td>\n<td data-col-size=\"md\">let maxUsers = 100; maxUsers = 200<\/td>\n<td data-col-size=\"md\">Compiler error \u2014 good!<\/td>\n<td data-col-size=\"xl\">let protects you from bugs<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Using var for values that never change<\/td>\n<td data-col-size=\"md\">var pi = 3.14159<\/td>\n<td data-col-size=\"md\">let pi = 3.14159<\/td>\n<td data-col-size=\"xl\">False expectation \u2014 looks like it may change<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Declaring loop counters as let<\/td>\n<td data-col-size=\"md\">for let i in 0..&lt;10 { i += 1 }<\/td>\n<td data-col-size=\"md\">for i in 0..&lt;10 { \u2026 } (implicitly mutable)<\/td>\n<td data-col-size=\"xl\">Loop variable is mutable by default<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Making struct properties let when they should be editable<\/td>\n<td data-col-size=\"md\">struct User { let name: String }<\/td>\n<td data-col-size=\"md\">var name if user can change it<\/td>\n<td data-col-size=\"xl\">Immutability is good, but not when it blocks real use<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">6. Quick Summary \u2013 Decision Checklist (use this every time)<\/h3>\n<p dir=\"auto\">When you write:<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let\/var something = \u2026<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">Ask yourself:<\/p>\n<ol dir=\"auto\">\n<li>Will I <strong>ever need to completely replace<\/strong> this value with a different value later? \u2192 <strong>Yes<\/strong> \u2192 var \u2192 <strong>No \/ probably not<\/strong> \u2192 let<\/li>\n<li>Is this value part of the <strong>identity<\/strong> or <strong>fixed state<\/strong> of the object? \u2192 Usually let (id, createdAt, email\u2026)<\/li>\n<li>Is this value <strong>user-editable<\/strong> or <strong>changes over time<\/strong>? \u2192 Usually var (displayName, score, isPremium\u2026)<\/li>\n<li>Inside a function \u2014 is this a <strong>temporary calculation<\/strong> that won\u2019t be reassigned? \u2192 Almost always let<\/li>\n<\/ol>\n<h3 dir=\"auto\">7. Small Practice \u2013 Choose let or var<\/h3>\n<p dir=\"auto\">For each line, decide let or var and explain why:<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>____ maximumUsers = 1000\r\n____ currentScore = 0\r\n____ apiKey = \"xyz123\"\r\n____ temperature = 32.5\r\n____ playerName = \"Aarav\"\r\n____ playerName = getNewNameFromServer()\r\n____ isDarkMode = traitCollection.userInterfaceStyle == .dark\r\n____ counter = 0; counter += 1 (in loop)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Expected answers<\/strong> (and reasoning):<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let maximumUsers = 1000             \/\/ fixed limit, never changes\r\nvar currentScore = 0                \/\/ definitely increases\r\nlet apiKey = \"xyz123\"               \/\/ fixed secret\r\nvar temperature = 32.5              \/\/ can change over time\r\nlet playerName = \"Aarav\"            \/\/ fixed at creation\r\nvar playerName = getNewNameFromServer()   \/\/ value changes\r\nlet isDarkMode = traitCollection.userInterfaceStyle == .dark   \/\/ computed once, not reassigned\r\nvar counter = 0                     \/\/ counter must increase<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">Paste your decisions here if you want feedback!<\/p>\n<p dir=\"auto\">What would you like to explore next?<\/p>\n<ul dir=\"auto\">\n<li>Mutability inside <strong>structs vs classes<\/strong> (very important difference)<\/li>\n<li>let with <strong>computed properties<\/strong> &amp; <strong>lazy properties<\/strong><\/li>\n<li>When var is actually safer (mutable state in view models\u2026)<\/li>\n<li>Mutability in <strong>SwiftUI<\/strong> (@State vs let, @Binding)<\/li>\n<li>Or move to another topic (loops, functions, optionals, switch\u2026)<\/li>\n<\/ul>\n<p dir=\"auto\">Just tell me \u2014 we\u2019ll continue in the same clear, detailed, teacher-like style \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. The Core Idea \u2013 What \u201cmutability\u201d really means In Swift, mutability = \u201ccan this thing be changed after I create it?\u201d Swift gives you two keywords to control mutability: let = constant \u2192&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[],"class_list":["post-2724","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2724","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/comments?post=2724"}],"version-history":[{"count":1,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2724\/revisions"}],"predecessor-version":[{"id":2725,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2724\/revisions\/2725"}],"wp:attachment":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/media?parent=2724"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/categories?post=2724"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/tags?post=2724"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}