Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to declare an optional value as nil explicitly in Struct - Swift

Tags:

swift

Here's a quote from the docs:

If your custom type has a stored property that is logically allowed to have “no value”—perhaps because its value cannot be set during initialization, or because it is allowed to have “no value” at some later point—declare the property with an optional type. Properties of optional type are automatically initialized with a value of nil, indicating that the property is deliberately intended to have “no value yet” during initialization.

If I do this with a class it works fine:

class MyClass {
    var someProperty: String?
}

var myClass = MyClass()
myClass.someProperty // Shows nil

However, if I do this with a struct type, I get an error on initialization:

struct MyStruct {
    var someProperty: String?
}

// ERROR
var myStruct = MyStruct()

Error:

Missing argument for parameter 'someProperty'

I can remedy this by declaring it nil explicitly like so:

struct MyStruct {
    var someProperty: String? = nil
}

// Valid
var myStruct = MyStruct()

Question

Given the documentation, I would expect properties on any type that are set as optionals to be defaulted to nil. Is there a reason I have to declare it explicitly on a struct?

Why?

No good reason, like many of you, I'm just experimenting.

like image 366
Logan Avatar asked Jun 05 '14 16:06

Logan


People also ask

How do you declare an optional variable in Swift?

Forced Unwrapping If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. This just means putting an exclamation mark at the end of the variable. Optional("Hello, Swift 4!")

What should you use to provide a default value for an optional type variable in Swift?

Use the nil-coalescing operator ( ?? ) to supply a default value in case the Optional instance is nil .

Is nil a value in Swift?

In Swift: nil is not a pointer, it's the absence of a value of a certain type. NULL and nil are equal to each other, but nil is an object value while NULL is a generic pointer value ((void*)0, to be specific). [NSNull null] is an object that's meant to stand in for nil in situations where nil isn't allowed.


2 Answers

Both Classes and Structs need to have all property values set when they are initialized. This can be done either through explicit default values or by setting a value in the designated initializer.

However, Structs differ in the fact that they have an automatically generated memberwise initializer.

When you don't define a value for someProperty explicitly, your struct has one initializer only: the automatically generated memberwise one.

If you do provide a default value, you get two: one that takes no arguments, and one that takes a value for someProperty as an argument

From the docs:

All structures have an automatically-generated memberwise initializer, which you can use 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:

let vga = Resolution(width: 640, height: 480)

Unlike structures, class instances do not receive a default memberwise initializer. Initializers are described in more detail in Initialization.

like image 85
Cezar Avatar answered Sep 25 '22 23:09

Cezar


I agree this is rather quirky (unless I'm also missing something). For structures with only optionals, it might be worth suggesting (via Apple bugreport) that in such cases, a default parameterless initialiser is also added by default?

Another remedy is

var myStruct = MyStruct(someProperty:nil)

However, if you had a lot of optional members, this becomes clumbsy.

like image 27
user3675131 Avatar answered Sep 21 '22 23:09

user3675131