Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional parameter in enum case in swift

Tags:

enums

swift

In swift a function can have a optional parameters that have default values such as:

func f(a:Int, b:Int?=nil) {}

f(1);
f(1,2);

I'd like to do this with associated values with an enum. Following from this post about type safe url routes, I'd like to have a route which can take an optional parameter, such as:

enum StopPoint {
    case Search(query:String, limit:Int?=nil)
}

However it says I can't have an default value for a parameter in a tuple. However it is possible to have a case such as case Arrivals(stopId:Int), yet it is not possible in general to have a tuple with one named parameter.

So is it possible to have an enum with a default parameter, and is the associated value a tuple or not?

like image 280
Jonathan. Avatar asked Dec 24 '15 18:12

Jonathan.


People also ask

What is optional in Swift enum?

An Optional is a type on its own, actually one of Swift's new super-powered enums. It has two possible values, None and Some(T) , where T is an associated value of the correct data type available in Swift. String? is actually syntactic sugar for Optional, and Optional is a type in its own right.

Can an enum be optional?

An optional represents two possible states: either there is value or there isn't a value at all. Where optionals only represent two possible states, enums are able to specify and combine multiple “stateful” properties into a single state representation.

What is associated value in enum Swift?

In Swift enum, we learned how to define a data type that has a fixed set of related values. However, sometimes we may want to attach additional information to enum values. These additional information attached to enum values are called associated values.

Can we implement protocol in enum?

Yes, enums can conform protocols. You can use Swift's own protocols or custom protocols. By using protocols with Enums you can add more capabilities. Sometimes we need to use similar but different object types in the same place.


2 Answers

What you can do is:

enum StopPoint {
    case Search(query: String, limit: Int?)

    init(query: String, limit: Int? = nil) {
        self = .Search(query: query, limit: limit)
    }
}

let foo = StopPoint(query: "default")             // Search("default", nil)
let bar = StopPoint(query: "special", limit:  42) // Search("special", Optional(42))
like image 144
0x416e746f6e Avatar answered Oct 07 '22 19:10

0x416e746f6e


You can do this by creating static functions on the enum that matches the enum case that you want to allow optional parameters for.

enum StopPoint {
    case search(query: String, limit: Int?)

    static func search(query: String) -> StopPoint {
        return .search(query: query, limit: nil)
    }
}

This makes it so that you can both provide the limit, or not, using the expected syntax:

let a = StopPoint.search(query: "Foobar")
let b = StopPoint.search(query: "Foobar", limit: 5)
let c = StopPoint.search(query: "Foobar", limit: nil)

func foo(_ stop: StopPoint) { /* ... */ }

foo(.search(query: "Foobar"))
foo(.search(query: "Foobar", limit: 5))
foo(.search(query: "Foobar", limit: nil))

Tested and confirmed working with Swift 4.2

like image 43
Linus Unnebäck Avatar answered Oct 07 '22 18:10

Linus Unnebäck