{"id":2746,"date":"2026-02-05T12:11:06","date_gmt":"2026-02-05T12:11:06","guid":{"rendered":"https:\/\/demo.materiamedica.net\/demo6\/?p=2746"},"modified":"2026-02-05T12:11:06","modified_gmt":"2026-02-05T12:11:06","slug":"chapter-80-swift-structs","status":"publish","type":"post","link":"https:\/\/demo.materiamedica.net\/demo6\/chapter-80-swift-structs\/","title":{"rendered":"Chapter 80: Swift Structs"},"content":{"rendered":"<h3 dir=\"auto\">1. What is a Struct? (the clearest possible explanation)<\/h3>\n<p dir=\"auto\">A <strong>struct<\/strong> (structure) is a <strong>value type<\/strong> that lets you <strong>group related data<\/strong> together and usually add <strong>behavior<\/strong> (methods) to that data.<\/p>\n<p dir=\"auto\">In simple words:<\/p>\n<blockquote dir=\"auto\">\n<p dir=\"auto\">A struct is like a <strong>custom data bag<\/strong> that you design yourself.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Real-life analogy (the one that clicks for almost everyone):<\/p>\n<p dir=\"auto\">Think of a <strong>visiting card<\/strong> \/ <strong>name card<\/strong> you give someone at a meeting.<\/p>\n<p dir=\"auto\">That card contains:<\/p>\n<ul dir=\"auto\">\n<li>Your name<\/li>\n<li>Your phone number<\/li>\n<li>Your company<\/li>\n<li>Your email<\/li>\n<li>Your designation<\/li>\n<\/ul>\n<p dir=\"auto\">You can make <strong>thousands of copies<\/strong> of your card and give them to people \u2014 each copy is <strong>independent<\/strong>.<\/p>\n<p dir=\"auto\">If someone writes a note on their copy (\u201ccall him tomorrow\u201d), <strong>your original card doesn\u2019t change<\/strong>.<\/p>\n<p dir=\"auto\">That is exactly how <strong>structs<\/strong> behave in Swift.<\/p>\n<ul dir=\"auto\">\n<li>When you assign a struct to a new variable \u2192 you get a <strong>full copy<\/strong> (not a reference)<\/li>\n<li>Changing one copy <strong>does not affect<\/strong> any other copy<\/li>\n<\/ul>\n<p dir=\"auto\">This is the <strong>opposite<\/strong> of classes (which are reference types).<\/p>\n<h3 dir=\"auto\">2. Creating your first struct \u2014 every part explained<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>struct Person {\r\n    \/\/ Stored properties \u2014 the actual data\r\n    let name: String            \/\/ cannot be changed after creation\r\n    var age: Int                \/\/ can be changed later\r\n    var city: String?           \/\/ optional \u2014 may be nil\r\n    \r\n    \/\/ Computed property \u2014 calculated on the fly\r\n    var greeting: String {\r\n        let cityText = city ?? \"somewhere\"\r\n        return \"Hi, I'm \\(name), \\(age) years old, from \\(cityText)\"\r\n    }\r\n    \r\n    \/\/ Method \u2014 behavior\r\n    mutating func haveBirthday() {\r\n        age += 1\r\n        print(\"Happy birthday! Now I'm \\(age) \ud83c\udf82\")\r\n    }\r\n    \r\n    \/\/ Initializer (custom \u2014 optional)\r\n    init(name: String, age: Int, city: String? = nil) {\r\n        self.name = name\r\n        self.age = age\r\n        self.city = city\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">3. Creating objects (instances) from the struct<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>\/\/ Create concrete persons\r\nvar rahul = Person(name: \"Rahul Verma\", age: 27, city: \"Bengaluru\")\r\nvar priya = Person(name: \"Priya Reddy\", age: 24)\r\n\r\n\/\/ Use them\r\nprint(rahul.greeting)           \/\/ Hi, I'm Rahul Verma, 27 years old, from Bengaluru\r\nprint(priya.greeting)           \/\/ Hi, I'm Priya Reddy, 24 years old, from somewhere\r\n\r\n\/\/ Change mutable property\r\nrahul.age = 28\r\nrahul.haveBirthday()            \/\/ Happy birthday! Now I'm 29 \ud83c\udf82\r\n\r\n\/\/ Important: priya is unchanged\r\nprint(priya.age)                \/\/ still 24\r\n\r\n\/\/ Assigning creates a COPY\r\nvar anotherRahul = rahul\r\nanotherRahul.age = 50\r\n\r\nprint(rahul.age)                \/\/ still 29 \u2014 copy was modified, original unchanged\r\nprint(anotherRahul.age)         \/\/ 50<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Key memory fact<\/strong> (you must understand this):<\/p>\n<p dir=\"auto\"><strong>Structs are value types<\/strong> \u2192 assigning var b = a \u2192 <strong>full copy<\/strong> is made \u2192 changing b <strong>never<\/strong> changes a<\/p>\n<p dir=\"auto\">(Classes are reference types \u2014 both variables point to the same object in memory.)<\/p>\n<h3 dir=\"auto\">4. Real-life examples \u2014 structs you will actually write every day<\/h3>\n<h4 dir=\"auto\">Example 1 \u2013 Product in shopping cart \/ e-commerce<\/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 Product {\r\n    let id: String\r\n    let name: String\r\n    let price: Decimal\r\n    var quantity: Int = 1\r\n    \r\n    var subtotal: Decimal {\r\n        price * Decimal(quantity)\r\n    }\r\n    \r\n    mutating func increaseQuantity(by step: Int = 1) {\r\n        quantity += step\r\n    }\r\n    \r\n    mutating func decreaseQuantity(by step: Int = 1) {\r\n        guard quantity &gt; step else { return }\r\n        quantity -= step\r\n    }\r\n}\r\n\r\nvar cart: [Product] = []\r\n\r\ncart.append(Product(id: \"P001\", name: \"Wireless Earbuds\", price: 3499))\r\ncart.append(Product(id: \"P002\", name: \"Phone Case\", price: 799))\r\n\r\n\/\/ Increase quantity of first item\r\ncart[0].increaseQuantity(by: 2)\r\n\r\nvar total: Decimal = 0\r\nfor item in cart {\r\n    total += item.subtotal\r\n}\r\n\r\nprint(\"Cart total: \u20b9\\(total)\")<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 2 \u2013 Todo \/ Task item (very common in productivity apps)<\/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 TodoItem {\r\n    let id: UUID = UUID()\r\n    var title: String\r\n    var isCompleted: Bool = false\r\n    let createdAt: Date = Date()\r\n    \r\n    mutating func toggleCompletion() {\r\n        isCompleted.toggle()\r\n    }\r\n    \r\n    var statusEmoji: String {\r\n        isCompleted ? \"\u2705\" : \"\u23f3\"\r\n    }\r\n}\r\n\r\nvar todos: [TodoItem] = []\r\n\r\ntodos.append(TodoItem(title: \"Finish Swift lesson\"))\r\ntodos.append(TodoItem(title: \"Buy groceries\"))\r\n\r\ntodos[0].toggleCompletion()\r\n\r\nfor todo in todos {\r\n    print(\"\\(todo.statusEmoji) \\(todo.title)\")\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 3 \u2013 Location \/ coordinate (very common in maps &amp; location apps)<\/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 Location {\r\n    let latitude: Double\r\n    let longitude: Double\r\n    var name: String?\r\n    \r\n    var coordinateString: String {\r\n        String(format: \"%.4f, %.4f\", latitude, longitude)\r\n    }\r\n    \r\n    func distance(to other: Location) -&gt; Double {\r\n        \/\/ simple Euclidean distance (real app would use proper haversine)\r\n        let dx = latitude - other.latitude\r\n        let dy = longitude - other.longitude\r\n        return sqrt(dx*dx + dy*dy)\r\n    }\r\n}\r\n\r\nlet hyderabad = Location(latitude: 17.3850, longitude: 78.4867, name: \"Hyderabad\")\r\nlet bangalore  = Location(latitude: 12.9716, longitude: 77.5946, name: \"Bengaluru\")\r\n\r\nprint(\"Distance approx: \\(hyderabad.distance(to: bangalore))\")\r\nprint(\"Hyderabad coordinates: \\(hyderabad.coordinateString)\")<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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=\"md\">Mistake<\/th>\n<th data-col-size=\"md\">Wrong \/ Risky code<\/th>\n<th data-col-size=\"lg\">Correct \/ Better habit<\/th>\n<th data-col-size=\"md\">Why?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"md\">Using var for everything<\/td>\n<td data-col-size=\"md\">var name: String everywhere<\/td>\n<td data-col-size=\"lg\">Default to let unless you actually reassign<\/td>\n<td data-col-size=\"md\">let prevents bugs + better safety<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Force-unwrapping optionals in struct<\/td>\n<td data-col-size=\"md\">var city: String = address!.city<\/td>\n<td data-col-size=\"lg\">var city: String? or proper optional handling<\/td>\n<td data-col-size=\"md\">Crash if address is nil<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Making everything public<\/td>\n<td data-col-size=\"md\">public struct User { \u2026 } everywhere<\/td>\n<td data-col-size=\"lg\">Default = internal \u2014 use public only when needed<\/td>\n<td data-col-size=\"md\">Better encapsulation &amp; API control<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Forgetting mutating for methods that change self<\/td>\n<td data-col-size=\"md\">func increaseAge() { age += 1 }<\/td>\n<td data-col-size=\"lg\">mutating func increaseAge() { age += 1 }<\/td>\n<td data-col-size=\"md\">Compile error if missing mutating<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Using class when struct is better<\/td>\n<td data-col-size=\"md\">class Point { let x: Double; let y: Double }<\/td>\n<td data-col-size=\"lg\">Use struct unless you need reference semantics<\/td>\n<td data-col-size=\"md\">Struct is safer, faster, thread-safe by default<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">6. Quick Summary \u2014 Struct vs Class (decision you make every day)<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Question \/ Feature<\/th>\n<th data-col-size=\"lg\">Struct (value type)<\/th>\n<th data-col-size=\"lg\">Class (reference type)<\/th>\n<th data-col-size=\"md\">Most developers choose\u2026<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">Identity matters (=== checks same instance)<\/td>\n<td data-col-size=\"lg\">No \u2014 every copy is independent<\/td>\n<td data-col-size=\"lg\">Yes \u2014 two variables can point to same object<\/td>\n<td data-col-size=\"md\">Struct unless identity matters<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Can inherit from another type<\/td>\n<td data-col-size=\"lg\">No<\/td>\n<td data-col-size=\"lg\">Yes (single inheritance)<\/td>\n<td data-col-size=\"md\">Struct unless you need inheritance<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Can be used as key in Dictionary\/Set<\/td>\n<td data-col-size=\"lg\">Yes (if Hashable)<\/td>\n<td data-col-size=\"lg\">Yes (but need careful Hashable implementation)<\/td>\n<td data-col-size=\"md\">Struct almost always<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Copy behavior<\/td>\n<td data-col-size=\"lg\">Copied on assignment \/ pass<\/td>\n<td data-col-size=\"lg\">Reference (pointer) copied<\/td>\n<td data-col-size=\"md\">Struct safer<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Thread safety (mutable shared state)<\/td>\n<td data-col-size=\"lg\">Safer (each copy independent)<\/td>\n<td data-col-size=\"lg\">Can cause data races<\/td>\n<td data-col-size=\"md\">Struct preferred<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Typical use in SwiftUI<\/td>\n<td data-col-size=\"lg\">@State, @ObservedObject (structs)<\/td>\n<td data-col-size=\"lg\">ObservableObject \/ @StateObject<\/td>\n<td data-col-size=\"md\">Struct for most data<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Modern Swift recommendation (2025\u20132026)<\/strong>:<\/p>\n<blockquote dir=\"auto\">\n<p dir=\"auto\"><strong>Default to struct<\/strong> for almost everything Use <strong>class<\/strong> only when you need:<\/p>\n<ul dir=\"auto\">\n<li>reference semantics (shared mutable state)<\/li>\n<li>inheritance<\/li>\n<li>Objective-C interop<\/li>\n<li>identity comparison (===)<\/li>\n<\/ul>\n<\/blockquote>\n<h3 dir=\"auto\">7. Small Practice \u2014 Try these<\/h3>\n<ol dir=\"auto\">\n<li>Create a Person struct with:\n<ul dir=\"auto\">\n<li>let name: String<\/li>\n<li>var age: Int<\/li>\n<li>mutating func haveBirthday()<\/li>\n<\/ul>\n<\/li>\n<li>Create a BankAccount struct like the example above\n<ul dir=\"auto\">\n<li>private var balance: Double<\/li>\n<li>init(initialDeposit:)<\/li>\n<li>mutating func deposit(amount:)<\/li>\n<li>mutating func withdraw(amount:) -&gt; Bool<\/li>\n<\/ul>\n<\/li>\n<li>Create a Location struct like the example\n<ul dir=\"auto\">\n<li>let latitude: Double, longitude: Double<\/li>\n<li>var name: String?<\/li>\n<li>computed coordinateString<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p dir=\"auto\">Paste your code here if you want feedback or want to see more polished versions!<\/p>\n<p dir=\"auto\">What would you like to explore next?<\/p>\n<ul dir=\"auto\">\n<li><strong>Struct vs Class<\/strong> \u2014 detailed comparison &amp; decision guide<\/li>\n<li><strong>Mutability<\/strong> inside structs (mutating methods)<\/li>\n<li><strong>Struct initializers<\/strong> (default, custom, memberwise)<\/li>\n<li><strong>Structs in SwiftUI<\/strong> (@State, value types, performance)<\/li>\n<li>Or move to another topic (optionals, arrays, closures, switch\u2026)<\/li>\n<\/ul>\n<p dir=\"auto\">Just tell me \u2014 we\u2019ll continue in the same clear, detailed, patient style \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What is a Struct? (the clearest possible explanation) A struct (structure) is a value type that lets you group related data together and usually add behavior (methods) to that data. In simple words:&#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-2746","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2746","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=2746"}],"version-history":[{"count":1,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2746\/revisions"}],"predecessor-version":[{"id":2747,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2746\/revisions\/2747"}],"wp:attachment":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/media?parent=2746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/categories?post=2746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/tags?post=2746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}