I was busy using NSURLProtocolClient's URLProtocol function:
welf?.client?.URLProtocol(welf!, didReceiveResponse: operation.response, cacheStoragePolicy: NSURLCacheStoragePolicy.NotAllowed)
I was expecting it to return Void. But to my surprise it returns Void?
Why is it necessary to make a distinction between Void and Void?
I have read that Void is a type alias for the empty tuple type. So, does this have something to do with a distinction between the empty tuple type vs nil?
This is simply because you are using Optional Chaining. The method returns Void, but it is possible for the whole chain to return nil before the method is ever called.
Essentially, a return value of Void will mean the call was actually made (self and client both have values) while a nil result will mean that one of those were nil.
Note that, () and nil is different:
let a:Void? = ()
let b:Void? = nil
a == nil // -> false
b == nil // -> true
Using this, you can judge the method has really been invoked or not.
let result = welf?.client?.URLProtocol(welf!, didReceiveResponse: operation.response, cacheStoragePolicy: NSURLCacheStoragePolicy.NotAllowed)
if result != nil {
// success
}
else {
// `welf?.client` was `nil`
}
Related
This question already has answers here:
What is an optional value in Swift?
(15 answers)
When two optionals are assigned to an if let statement, which one gets unwrapped? Swift language
(1 answer)
Closed 5 years ago.
I've searched in a lot of places and communities among the internet to find what the heck is happening in this programing syntax.
I'm seeking, desperately, for guidance in this code.
What is happening with the compiler in these specific declarations?
transitions[prev]?[transition]
transitions[state]?[transition] != nil
This is how the class is declared
public final class StateMachine<State: Hashable, Transition: Hashable>
This is the variables
public var state: State
private var transitions = [State:[Transition:State]]()
And these are the examples:
First situation - What is happening in the transitions[prev]?[transition]
public final func advance(transition: Transition, observe: Observer? = nil) -> State {
let prev = state
if let next = transitions[prev]?[transition], next != prev {
state = next
observe?(prev, next)
}
return state
Second situation - What is happening in the return transitions[state]?[transition] != nil
public final func canAdvance(transition: Transition) -> Bool {
return transitions[state]?[transition] != nil
}
That's all i want to understand. What is happening in these moments?
The question mark operator signifies optionality in Swift.
You can declare many things a optional, meaning they could be nil or hold a value. This includes for example variable declarations, computed properties, return values of functions and callbacks/closures. Also certain operations like casting or retrieving values from dictionaries will yield optional values.
When you want to use the value contained you have to unwrap them, cause there might not be one and the may be pointing to nil. There are many ways and forms of unwrapping and optionality chaining.
Explaing your particular examples:
In a dictionary retrieving a stored value via a key as in myDict[myKey] returns an optional value. The value for the key stored within your specific dictionary is another dictionary. By declaring transitions[state]?[transition] you say basically "if there is a dictionary found for the key state, go ahead and continue with this dictionary and get the value for the key transition for that dictionary, otherwise use nil".
This code:
return transitions[state]?[transition] != nil
is basically a shorter way of writing this:
if let stateDict = transitions[state] {
return stateDict[transition] != nil
} else {
return false
}
Your other example is about an optional closure passed into a function. You can also pass optional closures into functions and call them via closure?(). The ? signifies that if nil is passed for the closure, nothing should be done, otherwise it should be executed.
This code:
observe?(prev, next)
is basically a shorter way of writing this:
if let observeClosure = observe {
observeClosure(prev, next)
}
Some more optionality explanations:
If you work with an optional value from a declared variable you can safely unwrap it like so:
func square(myValue: Int?) → Int {
guard let myValue = myValue else {
return 0
}
return myValue * myValue
}
or
func square(myValue: Int?) → Int {
if let myValue = myValue {
return myValue * myValue
} else {
return 0
}
}
or you could define a fallback with the ?? operator
func square(myValue: Int?) → Int {
return myValue ?? 0 * myValue ?? 0
}
You could also use the ! operator to unwrap unsafely and if nil is found your app would crash. You should never do that unless you can guarantee that nil cannot be found like in:
func square(myValue: Int?) → Int {
if myValue != nil {
myValue! * mayValue! {
} else {
return 0
}
}
In brief, transitions[state]?[transition] from time to time can be nil.
So, if let next = transitions[prev]?[transition] unwraps this variable moves the algorithm inside if-parenthesis
if let next = transitions[prev]?[transition] {
// this code executes here if 'transitions[prev]?[transition]' is not nil
state = next
observe?(prev, next) // this closure possibly can be nil. if nil Swift just skips this line
}
Following code
extension String {
func isValidEmail() -> Bool {
if self == nil { return false }
Gives me error Value of type 'String' can never be nil, comparison isn't allowed
Is it possible to somehow check for nil here?
Checking for nil there is not required.
That function is an instance function on String.
It can only ever be run on an instance of String.
Secondly Swift does not have "nil messaging" like Objective-C so the String instance that the function is called on HAS to be not nil. Even in Objective-C this would still not matter as the function would not run if called on a nil String.
So, the message is correct, Value of type "String" can never be nil.
You could check if your string is empty as:
var myString : String?
if myString.isEmpty {
// do whatever you want ..
}
That's has more sense..
Recall that in Swift, values of type String can never be nil; if you wanted a nillable value, you'd have to declare it String?.
So no, there is no way to check if a String variable is set to nil, because it can't.
I am getting error:
initialiser for conditional binding must have optional type, not '()'.
Using Swift language, below is the code:
if let result = brain.performOperation(operation)
I think I can answer your question, but I don't know how much it will help you.
The way if let someVar = someOptional { } is used is to check the value of a variable (someOptional) to see if it is nil or a "value". If it is not nil then someVar will be assigned the non-nil value of someOptional and execute the code between { } which can safely reference someVar, knowing it is not nil. If someOptional is nil then the code within { } is bypassed and not executed.
The comment you posted above indicates that the performOperation() method is this:
func performOperation(symbol:String) {
if let operation = knownOps[symbol] {
opStack.append(operation)
}
}
This method does not return anything, or more formally it returns void aka (). void, or () is not a value, nor is it nil.
So when you have this statement
if let result = brain.performOperation(operation) { }
the compiler complains because it expects brain.performOperation(operation)
to return either nil or a value, but not void aka () which is exactly what the method returns.
If you are still confused about optionals, be sure to read as much as you can of the Swift Language Reference. Optionals are a big part of the language and once you get used to them you will find them very invaluable.
I noticed that the empty tuple () is used to represent an absence of value in Swift. For example, the signature of a function that returns nothing, is:
func zz(){
println("zz")
}
The compiler will also accept this body for the function above:
func zz(){
println("zap")
return () // returning () and returning nothing is the same thing!
}
An equivalent way of defining this function would be:
func zz() -> (){
println("zap")
return ()
}
There's even a typealias for () called Void:
typealias Void = ()
So if the empty tuple is the absence of value in Swift, what is its relationship with nil? Why do we need both concepts? is nil defend in terms of ()?
nil is a special value that you can assign to an Optional to mean the optional doesn't have a value. nil is not really the absence of a value, it's a special value that means no proper value
() means that nothing is returned (or passed in), not even an optional. There is no return value, nor can there ever be. You can't assign it to anything unlike a return value of nil.
The situation is analogous to the difference between (in C)
void foo(void);
and
SomeType* bar(void);
if the latter function uses a return value of NULL to indicate some sort of failure. i.e.
someVariable = foo(); // Illegal
someVariable = bar(); // Not illegal
if (someVariable != NULL) { ... }
nil is absence of value, () is a tuple with 0 elements. Conceptually the same as comparing nil with an empty array: an empty array is not absence of value.
They are simply 2 different and unrelated things.
Just try this in a playground:
var x: Int?
x = () // <== () is not convertible to Int
that produces an error.
Let's say I have function which returns optional. nil if error and value if success:
func foo() -> Bar? { ... }
I can use following code to work with this function:
let fooResultOpt = foo()
if let fooResult = fooResultOpt {
// continue correct operations here
} else {
// handle error
}
However there are few problems with this approach for any non-trivial code:
Error handling performed in the end and it's easy to miss something. It's much better, when error handling code follows function call.
Correct operations code is indented by one level. If we have another function to call, we have to indent one more time.
With C one usually could write something like this:
Bar *fooResult = foo();
if (fooResult == null) {
// handle error and return
}
// continue correct operations here
I found two ways to achieve similar code style with Swift, but I don't like either.
let fooResultOpt = foo()
if fooResult == nil {
// handle error and return
}
// use fooResultOpt! from here
let fooResult = fooResultOpt! // or define another variable
If I'll write "!" everywhere, it just looks bad for my taste. I could introduce another variable, but that doesn't look good either. Ideally I would like to see the following:
if !let fooResult = foo() {
// handle error and return
}
// fooResult has Bar type and can be used in the top level
Did I miss something in the specification or is there some another way to write good looking Swift code?
Your assumptions are correct—there isn't a "negated if-let" syntax in Swift.
I suspect one reason for that might be grammar integrity. Throughout Swift (and commonly in other C-inspired languages), if you have a statement that can bind local symbols (i.e. name new variables and give them values) and that can have a block body (e.g. if, while, for), those bindings are scoped to said block. Letting a block statement bind symbols to its enclosing scope instead would be inconsistent.
It's still a reasonable thing to think about, though — I'd recommend filing a bug and seeing what Apple does about it.
This is what pattern matching is all about, and is the tool meant for this job:
let x: String? = "Yes"
switch x {
case .Some(let value):
println("I have a value: \(value)")
case .None:
println("I'm empty")
}
The if-let form is just a convenience for when you don't need both legs.
If what you are writing is a set of functions performing the same sequence of transformation, such as when processing a result returned by a REST call (check for response not nil, check status, check for app/server error, parse response, etc.), what I would do is create a pipeline that at each steps transforms the input data, and at the end returns either nil or a transformed result of a certain type.
I chose the >>> custom operator, that visually indicates the data flow, but of course feel free to choose your own:
infix operator >>> { associativity left }
func >>> <T, V> (params: T?, next: T -> V?) -> V? {
if let params = params {
return next(params)
}
return nil
}
The operator is a function that receives as input a value of a certain type, and a closure that transforms the value into a value of another type. If the value is not nil, the function invokes the closure, passing the value, and returns its return value. If the value is nil, then the operator returns nil.
An example is probably needed, so let's suppose I have an array of integers, and I want to perform the following operations in sequence:
sum all elements of the array
calculate the power of 2
divide by 5 and return the integer part and the remainder
sum the above 2 numbers together
These are the 4 functions:
func sumArray(array: [Int]?) -> Int? {
if let array = array {
return array.reduce(0, combine: +)
}
return nil
}
func powerOf2(num: Int?) -> Int? {
if let num = num {
return num * num
}
return nil
}
func module5(num: Int?) -> (Int, Int)? {
if let num = num {
return (num / 5, num % 5)
}
return nil
}
func sum(params: (num1: Int, num2: Int)?) -> Int? {
if let params = params {
return params.num1 + params.num2
}
return nil
}
and this is how I would use:
let res: Int? = [1, 2, 3] >>> sumArray >>> powerOf2 >>> module5 >>> sum
The result of this expression is either nil or a value of the type as defined in the last function of the pipeline, which in the above example is an Int.
If you need to do better error handling, you can define an enum like this:
enum Result<T> {
case Value(T)
case Error(MyErrorType)
}
and replace all optionals in the above functions with Result<T>, returning Result.Error() instead of nil.
I've found a way that looks better than alternatives, but it uses language features in unrecommended way.
Example using code from the question:
let fooResult: Bar! = foo();
if fooResult == nil {
// handle error and return
}
// continue correct operations here
fooResult might be used as normal variable and it's not needed to use "?" or "!" suffixes.
Apple documentation says:
Implicitly unwrapped optionals are useful when an optional’s value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter. The primary use of implicitly unwrapped optionals in Swift is during class initialization, as described in Unowned References and Implicitly Unwrapped Optional Properties.
How about the following:
func foo(i:Int) ->Int? {
switch i {
case 0: return 0
case 1: return 1
default: return nil
}
}
var error:Int {
println("Error")
return 99
}
for i in 0...2 {
var bob:Int = foo(i) ?? error
println("\(i) produces \(bob)")
}
Results in the following output:
0 produces 0
1 produces 1
Error
2 produces 99