Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift - can I call a struct default memberwise init from my custom init method?

If I create a swift struct with no init, then I can call the compiler-generated default memberwise initialiser, like so:

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate
}
let o = OrderFill(price: 2, qty: 1, timeStamp: someDate)

What I'd like to do is create a convenience init method to deserialise from a dictionary, which then chains to the default memberwise init. Something like

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate

    init(dict:[String:AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int
            qty: dict["qty"] as! Int
            timeStamp: try parseDate(dict["ts"] as! String)
    }
}
let o = OrderFill(someDict)

When I try write this code though, the compiler (Xcode 7.2) gives me the error "Extra argument 'qty' in call" as though it doesn't see the default memberwise and is trying to recursively call init(dictionary)

I can write my own memberwise init, or I can simply assign the properties directly from my init(dictionary), but it'd be nice if I could chain the call. Is there any way to do this in swift?

like image 886
Orion Edwards Avatar asked Jan 11 '16 18:01

Orion Edwards


People also ask

How do I add a custom initializer to a struct without losing its Memberwise initializer?

If you want to keep both the default initializer and your own custom ones, there's a simple trick: create your initializers inside an extension rather than as part of the main struct definition.

Can struct have init Swift?

To initialize a struct in Swift, you do not need to write the init method. This is because, by default, there is a memberwise initializer that does the job behind the scenes. let name: String? struct Fruit { let name: String? }

Can structs have Initializers?

In Swift, types defined as structs automatically get a default initializer synthesized by the compiler — a so-called “memberwise initializer”, as the compiler will generate it based on the given struct's members (that is, its stored properties).

What is member wise initialization in struct?

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. The example below defines a structure called Size with two properties called width and height .


2 Answers

Add your own initializer as an extension to your struct. Extensions cannot remove existing functionalities, so it will preserve struct's default initializer.

struct OrderFill {
    let price: Int
    let qty: Int
    let timeStamp: NSDate
}

extension OrderFill {

    init(dict: [String: AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int,
            qty: dict["qty"] as! Int,
            timeStamp: try parseDate(dict["ts"] as! String)
        )
    }
}

let o = OrderFill(someDict)
like image 164
Sebastian Osiński Avatar answered Sep 23 '22 04:09

Sebastian Osiński


From the apple docs about Initialization:

Structure types automatically receive a memberwise initializer if they do not define any of their own custom initializers

and

Note that if you define a custom initializer for a value type, you will no longer have access to the default initializer (or the memberwise initializer, if it is a structure) for that type. This constraint prevents a situation in which additional essential setup provided in a more complex initializer is circumvented by someone accidentally using one of the automatic initializers instead.

Therefore the answer is NO. You cannot provide a custom initializer and use the memberwise initializer at the same time.

It sounds like this swift evolution proposal talks about extending the capabilities of the current memberwise initializer. But of course that is not out yet, you can however still take a look to learn a bit about what the limitations of the current situation are.

like image 9
luk2302 Avatar answered Sep 27 '22 04:09

luk2302