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

let s1 = Struct1(myLet2: false, myLet3: "My url123")

The error is: missing argument for parameter myLet. Why is that? It has a default value.

3 Answers3

69

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
    }
}
Viktor
  • 1,020
  • 1
  • 9
  • 22
kellanburket
  • 12,250
  • 3
  • 46
  • 73
  • 2
    I'n not sure I understood, how do I get the `Struct1()` initializer plus the initializer with all the properties automatically? – Rodrigo Ruiz Sep 30 '17 at 03:25
  • 2
    This is no longer the case with Swift 5.1, where you don't need to provide a value for struct properties that have a default value when initializing a struct - https://github.com/apple/swift-evolution/blob/master/proposals/0242-default-values-memberwise.md. – Francesco Puglisi Nov 20 '19 at 08:10
17

Swift 5.1: The struct memberwise initialisation behaviour is changing in Swift 5.1 (which ships with Xcode 11) to behave more as you'd expect:

struct Struct1 {
  var myVar = "my var"
  let myLet2: Bool
  let myLet3: String
}

// Swift 5.1 generates a memberwise init as: 
// init(myVar: String = "my var", myLet2: Bool, myLet3: String)

so the following code will now work in Swift 5.1:

let s1 = Struct1(myLet2: false, myLet3: "My url123") 
let s2 = Struct1(myVar: "var1", myLet2: false, myLet3: "My url123")

For more details see the relevant Swift evolution proposal

Nick Ager
  • 1,227
  • 14
  • 15
  • Awesome! This was such a pain, especially if you have a structure with a long list of properties! – SeriousSam Aug 13 '19 at 09:00
  • 3
    Your example is wrong. In order for the compiler to synthesised the init with the default values you have to declare those values as `var`. Otherwise the values are immutable and once you initialised them with the assignment `let myLet = "my let"` you are no longer be able to modify them. – superpuccio Sep 25 '19 at 13:55
  • 2
    @superpuccio my mistake I've edited my answer to change the default value in the struct from a `let` to a `var` - thanks for pointing out my error. – Nick Ager Sep 26 '19 at 12:16
  • It's awesome way in Swift 5.1. Thanks Nick for sharing it. – Nilesh Kumar Jan 20 '20 at 05:18
  • 1
    "Your example is wrong. In order for the compiler to synthesised the init with the default values you have to declare those values as var. Otherwise the values are immutable and once you initialised them with the assignment let myLet = "my let" you are no longer be able to modify them. " That really sucks :(. Now if you want to use that shortcut syntax you have to have a mutable property on your struct. I wish they had some additional syntax so you could get the same behaviour, but with a let. – Rufus Mall Feb 15 '21 at 00:23
10

In swift 4

struct Struct1 {
    let myLet: String?
    let myLet2: Bool
    let myLet3: String 
    init(myLet: String? = nil, myLet2: Bool, myLet3: String) {
        self.myLet = myLet
        self.myLet2 = myLet2
        self.myLet3 = myLet3
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
Yllow
  • 326
  • 4
  • 7
  • 6
    This is not particularly related to Swift 4. Declaring default values in initializers is available since Swift 1.0 – vadian Dec 28 '17 at 09:37
  • 6
    Just put a remark on which swift version is written for this example for clarity purpose – Yllow Dec 28 '17 at 09:48