What does this two question mark mean? - swift

I met with this code, and I could not figure out what does this two question marks mean?
the Definition of this variable looks like following:
var featureImageSizeOptional: CGSize?
The code that makes me confused is:
let featureImageSize = featureImageSizeOptional ?? CGSizeZero

It's the coalescing operator. It returns the first expression (featureImageSizeOptional) if it's non-nil. If the first expression is nil, the operator returns the second expression (CGSizeZero).
See the Language Guide for more info.

The operator does not 'return the first expression' - it returns the unwrapped value of the first expression (if it is not nil). From the Apple documentation (emphasis mine):
The nil coalescing operator (a ?? b) unwraps an optional a if it
contains a value, or returns a default value b if a is nil. The
expression a is always of an optional type. The expression b must
match the type that is stored inside a.
The nil coalescing operator is shorthand for the code below:
a != nil ? a! : b
The code above uses the ternary conditional operator and *forced
unwrapping (a!) to access the value wrapped inside a when a is not
nil*, and to return b otherwise. The nil coalescing operator provides a
more elegant way to encapsulate this conditional checking and
unwrapping in a concise and readable form.

Related

How does the function of finding the maximum in the dictionary work?

Please explain to a beginner how the function of finding a maximum in the dictionary works.
I know there are more concise solutions, but I want to understand step by step what is going on here.
var someDictionary = ["One": 41, "Two": 17, "Three": 23]
func maxValue() {
let maxValueOfSomeDictionary = someDictionary.max { a, b in a.value < b.value }
print(maxValueOfSomeDictionary!.value)
}
maxValue()
someDictionary is a Dictionary. A Dictionary is a kind of Sequence (see the "Default Implementations" section of Dictionary to know that it's a Sequence). Sequences provide the method max(by:), which:
Returns the maximum element in the sequence, using the given predicate as the comparison between elements.
Swift has trailing-closure syntax, so you can write .max {...} instead of .max(by: { ... }). The two syntaxes are identical, but most developers use trailing-closure syntax when possible.
The parameter is defined as:
areInIncreasingOrder
A predicate that returns true if its first argument should be ordered before its second argument; otherwise, false.
The Element of Dictionary as a Sequence is a tuple (key: Key, value: Value), so this is the type that is passed to areInIncreasingOrder.
The closure defines two parameters, a and b, each of type (key: Key, value: Value). It returns whether a.value is less than b.value. Swift allows 1-statement closures to omit the return.
This paragraph is somewhat technical and you may want to skip it. The TL;DR is that max returns the maximum element according to your closure. Provided the closure obeys the rules defined in the docs, the max algorithm will return the maximum element, for a specific definition of "maximum," which is that there is no element in the sequence that is ordered after this one according to areInIncreasingOrder. This pedantic definition especially matters when there are incomparables in the list. Equal elements are (somewhat strangely IMO) defined as "incomparable" in that neither is before the other. This also matters for values like NaN.
This will return a maximum element, or nil if the Sequence is empty. (The docs say "the" maximum element, but in the case of incomparable elements, it is not promised which one will be returned.)
maxValueOfSomeDictionary is of type (key: String, value: Int)?, an optional version of the Element of the Dictionary, since it may be a value or it may be nil.
maxValueOfSomeDictionary! converts an Optional into its wrapped value, or crashes if the Optional is nil. This then prints the .value of that.
To see precisely how max operates, you can read the default implementation in stdlib.

Implicitly unwrapped optional strange behaviour with map

What I discovered
This question is about something I noticed a bit strange in the Swift language. I came across this behaviour, as it was a bug in my code.
If I created an array for a grid as an implicitly unwrapped optional, then map behaves strangely. Have a look at this code:
let grid: [[Int]]! = [ // May be defined like this if set later on
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(grid.map { $0[0] }!)
// Prints "[1, 2, 3]" (not what I wanted)
print(grid!.map { $0[0] })
// Prints "[1, 4, 7]" (what I wanted)
I know the row can be obtained simply by doing grid[0]. However, I am trying to get a column.
I tried the first method above, which only gives the row instead of the column. The second method worked and gave the column.
What is the cause?
I defined grid as [[Int]]!, which is an implicitly unwrapped optional.
Why do I need to force unwrap grid to use map properly?
Why does the first method act the same as returning a row using grid[0]?
There are two versions of map: one that operates on the array and one that operates on optionals.
Your grid is an optional, and even though it is an implicitly unwrapped optional (IUO) it is still an optional. Swift will treat an IUO as an optional whenever possible and only force unwraps the value when the unwrapped type is needed.
Because of this, the optional version of map is used instead of the one you expect. By explicitly unwrapping grid with !, you then allow the desired version of map to be used.
How does map work on an optional?
When map is applied to an optional, it applies the closure to the unwrapped value. If the optional is nil, nothing happens.
So, grid is unwrapped and becomes $0, and the closure returns $0[0] which is the first row of the grid.
Note: In Xcode, if you option-click on map in each statement you will see that the first says:
Evaluates the given closure when this Optional instance is not nil,
passing the unwrapped value as a parameter.
and the second one:
Returns an array containing the results of mapping the given closure
over the sequence’s elements.

Exclamation mark prefix on variables during if statements and other as well?

I'm very confused even after looking through similar questions of what the(!) operator does when it is prefixed on a variable or other object in if statements, functions, etc?
Example:
mutating func add(value: T)
{
if !contains(items, value)
{
items.append(value)
}
}
the exclamation mark ! is used for two purposes. When you see it appear at the beginning of an object, such as in !contains(items, values), it means "NOT". For example...
let x = 10
let y = 5
if x == y {
print("x is equal to y")
} else if x != y {
print("x is NOT equal to y")
}
The above code will print => "x is NOT equal to y" .
The logical NOT (!) operator can be used to reverse boolean values. For example...
var falseBoolValue = false
falseBoolValue = !falseBoolValue
print(falseBoolValue)
The above code will print => "true"
In addition to the usage as the logical NOT operator, the exclamation mark is also used to implicitly unwrap optional values. Whenever you see the exclamation mark appear at the end of an object name, such as in someVariable!, it is being used to implicitly unwrap an optional value. Read about optionals to gain a better understanding of how ! is used with optional values.
it is NOT prefix there. Meaning your if looks for "items NOT containing value".

Complex case values in Swift

Swift has a rather nifty switch statement by the looks of it (at least compared to the other C derivatives) in that you can use values, lists, tuples, ranges and so on.
Its sequential processing nature makes this a very logical approach, but I'm wondering whether it supports more arbitrary objects for checking against, such as variables and other general expressions, such as with:
let check = 7
switch (value) {
case check:
println("exact");
case check * 2:
println("twice");
case check * 3:
println("thrice");
case valueInDb("mytable","mycolumn"):
println ("value in database");
default:
println("some other value");
}
What you are doing is called "Expression Pattern"
From this document:
An expression pattern represents the value of an expression. Expression patterns appear only in switch statement case labels.
The expression represented by the expression pattern is compared with the value of an input expression using the Swift standard library ~= operator. The matches succeeds if the ~= operator returns true. By default, the ~= operator compares two values of the same type using the == operator.
...
expression-pattern → expression­
So you can use any "expression" in switch case, and by default, it will be compared using == operator.

Do "!" and "nil" give the same result?

In objective-c is the end result of !variable the same as variable==nil Also I think I read somewhere that iVars are initialized to "nil" (i.e. o) but sadly I can't seem to find where I spotted it now. If I am correct is this initialization to nil part of declaring an iVar or is it linked to something else like #property?
i.e. do these evaluate the same ...
if(!myObject) ...
and
if(myObject == nil) ...
Cheers Gary.
Edited: hopefully for more clarity.
Your question subject and question body appear to be asking different things, so…
To answer the question subject: No, ! and nil are not at all the same. ! is an operator that returns the logical negation of its operand (that is, !0 returns 1 and ! with anything else returns 0), while nil is a macro for 0.
To answer the question itself: Yes, !foo and foo == nil give the same result for object variables. And yes, instance variables are initialized to 0. So are static variables and global variables.
! is a C logical operator that means not (like && means and and || means or).
nil is the way for expressing an unitialized object pointer.
Applied to a pointer, the value of the expression is TRUE whenever the pointer is NULL or nil.
In the end, if(!myObject) and if(myObject==nil) have the same behaviour.
In objective-c the ! is a boolean operator and returns the opposite of a boolean value or expression result. In the below example myObj is really evaluating it's pointer value as a boolean, zero or non-zero. Since myObj is a non-zero pointer this evaluates to true. !myObj will return the opposite, in this case it would return false.
id myObj = nil;
int x = 0;
if (myObj)
x++;