6

Question regarding Swift 2.1 in Xcode 7.

I have declared an optional variable like this:

var something: Int64?

I would like to later assign it to a dictionary key using a shorthand if, like this:

dictionary['something'] = (something != nil) ? something! : nil

XCode is giving me the following validation error:

Result values in '? :' expression have mismatching types: 'Int64' and '_'

What is the issue here? Why can't optional Int64 be nil?

JAL
  • 41,701
  • 23
  • 172
  • 300
Tarps
  • 1,928
  • 1
  • 11
  • 27
  • 1
    what is your `dictionary` type? – Dharmesh Kheni Jan 20 '16 at 14:28
  • I also found out that I apparently can't assign Int64 to AnyObject. Why's that? – Tarps Jan 20 '16 at 14:29
  • 2
    AnyObject can only hold class types, whereas Int64 is value type. Also, `'something'` is not a string, whereas `"something"` is. – dfrib Jan 20 '16 at 14:30
  • Cheers guys, that makes sense. I was also suggested that I should use NSNumber(), so I will probably go for that solution. I didn't realize Int64 is of different type than a regular Int. – Tarps Jan 20 '16 at 14:33
  • @Travo alternatively, if possible, use `Any` instead of `AnyObject`; the prior can hold also value types (e.g. Int64). – dfrib Jan 20 '16 at 14:36

4 Answers4

7

There are a number of problems here. First, Int64 isn't an AnyObject. None of the primitive number types are classes. They can be bridged to AnyObject using NSNumber, but you don't get that bridging automatically for Int64 (see MartinR's comment. I originally said this was because it was wrapped in an Optional, but it's actually because it's fixed-width).

Next, this syntax:

(something != nil) ? something! : nil

Is just a very complicated way to say something.

The tool you want is map so that you can take your optional and convert it to a NSNumber if it exists.

dictionary["something"] = something.map(NSNumber.init)

Of course, if at all possible, get rid of the AnyObject. That type is a huge pain and causes a lot of problems. If this were a [String: Int64] you could just:

dictionary["something"] = something
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 1
    Only Int/UInt (and Float, ...) are implicit bridged to NSNumber, *not* the fixed sized integer types like Int64 (observed e.g. here: http://stackoverflow.com/questions/28177435/storing-int64-in-userdefaults) – Martin R Jan 20 '16 at 14:38
  • 1
    @MartinR Thanks. Fixed. – Rob Napier Jan 20 '16 at 14:40
2

You can't add a Int64 to a dictionary of type [String : AnyObject], you need to wrap in in an NSNumber object. You can only store objects that conform to AnyObject in your dictionary.

var something: Int64?

something = 42

if let myVal: Int64 = something { // unwrap to make sure the value is there
    let myNum = NSNumber(longLong: myVal) // create an NSNumber from your Int64

    dictionary["something"] = myNum // insert it into the dictionary
}

As Anton Bronnikov said below, if your dictionary was type [String : Int64], you would be able to add your Int64 to it no problem.

JAL
  • 41,701
  • 23
  • 172
  • 300
1

It seems that others have already pointed out the issues with the types in your dictionary. I want to add that you can also use the nil coalescing operator '??' as even more concise shorthand for what you are doing in your example. It is most useful when you want to do a check for nil, (and if non-nil) unwrap the value and assign it, otherwise provide a default value.

var maybeSomething: Int?
var dictionary:[String:Int?] = [:]
dictionary["something"] = maybeSomething ?? nil
Mac Bellingrath
  • 575
  • 3
  • 9
0

something! has type Int64. Not optional Int64, but Int64. nil has type nil. You can't have an expression

condition ? Int64 : nil

What would be the type of it?

And the whole thing is pointless. On the right hand side you would have just "something". If that doesn't work then your dictionary doesn't accept optionals.

PS. Noticed that your dictionary wants to store Objective-C objects. In that case, no way it accepts an optional. And it only accepts an Int64 after converting to NSNumber.

gnasher729
  • 51,477
  • 5
  • 75
  • 98