longbow
longbow

Reputation: 1623

Swift Type vs explicitly unwrapped Type

I just wanted to use the .map closure in Swift and stumbled upon this:

//var oldUsers = [User]() -> containting >=1 Users at runtime
//var invitedUsers = [String]() -> gets filled with userIds during runtime by the user clicking on people to invite

let oldIds = self.oldUsers.map {$0.userId} //userId is of Type String!
println(oldIds) //-> returns Array<String!>

var allUsers = self.invitedUsers + oldIds

The last line wont compile as it says you cant combine

[(String)] and Array<String!>

Quick fixed it by just doing a cast in map

let oldIds = self.oldUsers.map {$0.userId as String}

Shouldnt that be the same? I would understand if I needed to unwrap an optional Array of [String?] first. Why is the cast necessary as the object property is already an explicitly unwrapped type of String?

Upvotes: 3

Views: 106

Answers (2)

afraisse
afraisse

Reputation: 3562

As you didn't explicitly give the type of your closure, Swift is inferring it for you.

Anyhow, I think casting the result type of your closure is a bit strange, and using the complete closure syntax would be better : let oldIds = self.oldUsers.map {(user) -> String in user.userId}

Here you explicitly tell Swift that your closure return type is String, so the map result type should be of [String].

Upvotes: 0

nhgrif
nhgrif

Reputation: 62072

[(String)] and Array<String!> are not at all the same thing.

Also, String! is not explicitly unwrapped, but rather implicitly unwrapped. It is called implicitly unwrapped because we can try to use it as a String without explicitly writing any unwrapping code. Meanwhile, explicitly writing the unwrap code is referred to as explicitly unwrapping...

But at the end of the day, the point is that [String] and [String!] are different types. They seem close enough, but Swift is very strict about its types.

What would be the result of combining these two arrays? Should it be a [String]? Or a [String!]? Either way, it's not the same as the two types that went into it, so it'd would be confusing. There's not a logical way to determine what sort of an array it should be.

So your options are to either cast the [String!] to a [String] and hope it holds no nil values, or to cast the [String] to a [String!], and then you can combine.

Upvotes: 4

Related Questions