Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Type vs explicitly unwrapped Type

Tags:

arrays

swift

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?

like image 969
longbow Avatar asked Jun 04 '26 15:06

longbow


1 Answers

[(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.

like image 130
nhgrif Avatar answered Jun 07 '26 10:06

nhgrif