Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift nil has a numeric value?

This is valid code in Swift:

println(nil < 1)

And the output will be true, likewise

println(nil > 1)

will be false (the number 1 is arbitrary, you can do the same for -1 and probably something else). The reason I ask is because I saw some code that tried to compare "some_string".toInt() to a numeric value and it compiled, which seems wrong considering toInt() returns Int?.

My question is, should this be valid syntax in Swift? If so, what is the numeric value of nil?


Swift 3.0 Update:

Looks like Swift Evolution tackled this issue by removing the optional comparison operators. This is no longer an issue in Swift 3.0 as it doesn't compile.

like image 800
Lucas Derraugh Avatar asked Oct 03 '14 03:10

Lucas Derraugh


People also ask

Is nil a value in Swift?

In Swift, nil means the absence of a value. Sending a message to nil results in a fatal error. An optional encapsulates this concept. An optional either has a value or it doesn't.

Is nil a type Swift?

In Swift, nil isn't a pointer—it's the absence of a value of a certain type. Optionals of any type can be set to nil , not just object types.

What does nil mean in Xcode?

If you're new to programming nil simply means that a variable (sometimes called an object) is empty and has no value assigned.


1 Answers

I believe what is happening is that the literal 1 is being implicitly typecast to the Int? type by the comparison to nil. For those who aren't used to Swift, I'll explain a little further. Swift has a concept called "optionals", which can either have a value or be nil. (For anyone familiar with Haskell, this is basically the Maybe monad.) It's illegal to assign nil to a variable that wasn't explicitly defined as optional, so let i: Int = nil will be rejected by the compiler. This allows for several benefits which are out of the scope of this answer, and it's a rather clever way to do it.

What's happening here, though, is that the literal 1 is a valid value of several types: Int, Int32, Int64, UInt32, UInt64, etc., etc., etc. And it's also a valid value of the optional versions of those types: Int?, Int32?, etc.

So when the Swift compiler sees a comparison between a literal value and nil, it tries to find a type that both these values would be valid for. 1 is a valid value of the Int? type, and nil is also a valid value of the Int? type, so it applies the comparison operator with the type signature (Int?, Int?) -> Bool. (That's the comparison operator that takes two Int? values and returns a Bool). That operator's rules say that nil values sort lower than anything else, even Int.min, and so you get the result seen in the OP's question.

like image 82
rmunn Avatar answered Oct 22 '22 16:10

rmunn