Struct Memberwise Initialization - Omitting Values for Properties That Have Defaults

Under what kind of circumstance would a stored property in a structure not have a default value?

struct Human {
var legs = 2
var name: String
}

is a structure where name does not have a default value. You can't have the default initializer Human(), because you can't provide the name; but you can use the memberwise initializer Human(legs: 1, name: "Lame Harry").

Can't initialize a struct with a default value

Swift 5.1:

Variables, marked with var are optional in constructors and their default value will be used. Example:

struct Struct {
var param1: Int = 0
let param2: Bool
}

let s1 = Struct(param2: false) // param1 = 0, param2 = false
let s2 = Struct(param1: 1, param2: true) // param1 = 1, param2 = true

For older versions of Swift (< 5.1):

Default Initialization is all-or nothing for a Struct. Either you define defaults for all properties and you get an automatically generated initializer Struct1() plus an initializer with all of the properties, or you get only the initializer with all of the properties, including any that happen to have a set default value. You're going to have to implement a custom initializer.

struct Struct1 {
let myLet = "my let"
let myLet2: Bool
let myLet3: String

init(myLet2: Bool, myLet3: String) {
self.myLet2 = myLet2
self.myLet3 = myLet3
}
}

Why it is called the Memberwise Initialiser

Regarding question 1:

There is an irrevocable law in Swift:

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

We are talking about structs:

When creating a struct you can use the default initializer (the pair of parentheses) if all properties have a default value.

If you just declare the properties without a default value, the compiler creates an implicit memberwise initializer – which you have to use – to make sure to assign a default value to each property in a very convenient way

Swift how to make the default initializer of a `struct` private

If you are noticing that implementing:

struct Foo {
let bar: String
static let sharedInstance = Foo(bar: "blah")
}

is legal even without giving bar an initial value, why? because Swift Structs have a default initializer, called the memberwise initializer:

Structure types automatically receive a memberwise initializer if they
do not define any of their own custom initializers. Unlike a default
initializer, the structure receives a memberwise initializer even if
it has stored properties that do not have default values.

The memberwise initializer is a shorthand way to initialize the member
properties of new structure instances. Initial values for the
properties of the new instance can be passed to the memberwise
initializer by name.

Meaning that if you tried to create a new instance of Foo struct, the compiler should -automatically- provide:

Sample Image

However, you can get rid of it by implementing private init(), but you have to make sure that all stored properties have -dummy- initial values (or maybe let them optionals...) because the struct no longer has an initializer for guaranteeing that the stored properties has values.

It should be similar to:

struct Foo {
var bar: String = ""
static var shared = Foo()

private init() {}
}

Remark: I would suggest to stuck with class when implementing a singleton pattern, you might want to check this answer (Thanks to
MartinR for mentioning it).

How to Deal with Default Initializer when variable are not initialized Using Struct

Need to set default value.

struct myFirstStruct {
var value1:String? = nil
var value2:String? = nil
}

let object = myFirstStruct()

Why omitting of structure property reports compile-time error

In Swift whenever we are going to create a structure. Swift automatically creates the default initializer for the particular structure. In your case, you will get a compile-time error in let zeroByTwo = Size(height: 2.0).

Sample Image

Because you are not passing all the parameters required by the default initializer. to fix that issue you can create your own init() functions in your structure as shown below.

struct Size {
var width:Double, height:Double

init(width:Double = 0.0, height:Double = 0.0){
self.width = width
self.height = height
}
}

let twoByTwo = Size(width: 2.0, height: 2.0)
let zeroByTwo = Size(width: 2.0)
let zeroByZero = Size()


Related Topics



Leave a reply



Submit