Difference between Initializing a Struct and Creating an Instance of a Struct?

I'm going through my Swift study notes and see something that's confusing me regarding creating an instance of a struct vs initializing a struct. I see the following in my notes:

An instance of a struct is an object created by using a pre-defined struct.

If you want to create an object using your struct as its blueprint, you must first “initialize” the struct.

To “initialize a struct is to create an actual object based on the struct (a blueprint) that you can then use.

This seems circular and has me confused. So I wanted to ask, is it that:

One can either

  1. initialize a struct explicitly by using init() in the struct definition
    which will “pre-iniitialize” it, or
  2. simply initialize a struct by creating an instance of the struct since structs are per-initialized in Swift?

Please help me clear this up. Thank you.

"initialize" just means "give a value". Ordinarily, memory is just sitting there in an "uninitialised" state, without any meaningful values.

When you make a struct (by calling one of its init methods or assigning it to a new variable), you are giving a value to some memory which didn't have a value before.

struct MyStruct {
  var value: Float
  init(value: Float) { 
    self.value = value 
  }
}

// These are the same. They both initialise a new struct.
let a = MyStruct(value: 42.0)
let b = a

You can get an instance of a Swift struct S in two ways:

  1. You can explicitly create a new one, by calling S.init() (or just S() for short) with the relevant, if anyt arguments.

    let s1 = S()
    
  2. You can copy another struct instance, by assignment, or passing as an arugment into a function. Doing so does not cause your initializer to be called. It does implicitly call some compiler-generated code, akin to a copy constructor in C. This copy construction's job is to copy all members over, including calling retain on all ARC managed objects that are members of the struct.

    let s1 = S() // "Initialization" happens here
    let s2 = s1 // A copy is made of s1, without initialization
    

An instance of a struct is an object created by using a pre-defined struct.

"instance" and "object" are synonymous, as far as I'm aware. However sometimes people use "instance", because most people usually associated objects with classes (and their associated reference semantics), from other programming lanugages

If you want to create an object using your struct as its blueprint, you must first “initialize” the struct.

I don't like using "struct" as a stand-in for "object", "instance", or "value", even though it technically makes sense when you expand the contraction ("I'll create a new structure over here..."). Doing so makes it ambiguous when you're talking about values (instances/objects) versus types, which makes conversations more confusing. But yes, if you want to create an object using your struct ("as its blueprint" is redundant, there's no other way to use a struct to make an object), you must call initializer of the struct type.

To “initialize a struct" is to create an actual object based on the struct (a blueprint) that you can then use.

Indeed. And in Swift, implicit in initialization is the act of allocation. Allocation sets aside some memory to be used for a new object. After allocation, the contents of that memory are still whatever happened to be residing before you took ownership of it. Technically, initialization is the process of initializing that memory so that all of its memory contains known values, not indeterminate junk from whoever used it last. "Initialization" in Swift refers to doing both, and calling your init to decide precisely what values to set the memory to.

initialize a struct explicitly by using init() in the struct definition
which will “pre-iniitialize” it, or

"Pre-initialize" isn't a thing

simply initialize a struct by creating an instance of the struct since structs are per-initialized in Swift

I don't know what this is asking.

1 Like

Thank you very much for this detailed response. Regarding the following text:

(..One can) simply initialize a struct by creating an instance of the struct since structs are pre-initialized in Swift

I learned in class that Swift automatically initializes structs and that one can do it explicitly using init() if one prefers. Is this not true?

Thank you so much, I appreciate it!

That is true. Also, you can have a variety of init(...) methods for a struct that initializes the struct for a variety of circumstances. These various init(...) methods have to be called explicitly, though.

The compiler makes a call to the init() default initializer if you don't explicitly call it yourself during the creation of an instance. Note that let s = S() is a shortcut for let s = S.init().

Same goes for classes and enums as well.

1 Like

Thank you for clearing that up for me, I understand now!

There's always an initializer being called (short of any compiler optimizations to elide them, but that's not important, conceptually). If you don't write a custom initializer, the compiler will synthesize one for you, called the member-wise initializer. This initializer has one parameter for every struct member that wasn't already assigned a value through static initialization. If you struct has no such unassigned members, then the memberwise initializer won't have any params.

1 Like