Implicitly unwrapped optional assign in Xcode 8 - ios

In Xcode 8 release version, i found a strange scene.
Here is the code,
let implicitlyUnwrappedOptionalString: String! = "implicitlyUnwrappedOptionalString"
let foo = implicitlyUnwrappedOptionalString
print(implicitlyUnwrappedOptionalString)
print(foo)
and here is the result:
implicitlyUnwrappedOptionalString
Optional("implicitlyUnwrappedOptionalString")
These above shows that when i assign a implicitly unwrapped optional to a variable without a explicit type, the type will be inferred to an optional type, not the type which it originally is, aka implicitly unwrapped optional.
My Xcode has been updated to 8. Anyone can verify the behavior in Xcode 7.x?
The change is due to the Swift version changing or the Xcode?

This is a consequence of SE-0054 Abolish ImplicitlyUnwrappedOptional type which has been implemented in Swift 3. Extract from that proposal (emphasis added):
However, the appearance of ! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; rather, it indicates that (1) the declaration has optional type, and (2) the declaration has an attribute indicating that its value may be implicitly forced. ...
If the expression can be explicitly type checked with a strong optional type, it will be. However, the type checker will fall back to forcing the optional if necessary. The effect of this behavior is that the result of any expression that refers to a value declared as T! will either have type T or type T?. For example, in the following code:
let x: Int! = 5
let y = x
let z = x + 0
… x is declared as an IUO, but because the initializer for y type checks correctly as an optional, y will be bound as type Int?. However, the initializer for z does not type check with x declared as an optional (there's no overload of + that takes an optional), so the compiler forces the optional and type checks the initializer as Int.
In your case, the assignment
let foo = implicitlyUnwrappedOptionalString
makes foo a strong optional, as in the example let y = x
from the proposal.
You could make foo an IUO by adding an explicit type annotation
let foo: String! = implicitlyUnwrappedOptionalString
but generally you should try to get rid from IUOs in your code,
as stated in the same proposal:
Except for a few specific scenarios, optionals are always the safer bet, and we’d like to encourage people to use them instead of IUOs.

Related

How to cast `Int8?` to `Int?`?

I have a UInt8? variable named seconds that I need to pass to a function accepting Int?.
This leads to Cannot convert value of type UInt8? to expected argument type Int?.
This means I have to cast, and so I tried the obvious:
Int?(seconds)
But this results in: UInt8? is not convertible to Int.
Of course I could do:
(seconds == nil) ? nil : Int(seconds!)
But WTF, does it really have to be so contrived?
Your type is Optional<UInt8>. A UInt8 can always be converted to an Int with the function Int.init. But since it's wrapped in an Optional, you'll have to map that function over the optional, yielding a new value of type Optional<Int>:
seconds.map(Int.init)
Optional.map(_:) and its companion flatMap often make working with optionals a lot easier.

what is the difference between "variable:Type" and "variable as Type" swift

What is the difference between:
let variable:Double = 23
and "as Type"?
let variable = 23 as Double
let variable:Double = 23
Declaring variable in this way is called Type Annotation in which we are telling complier explicitly that variable is type of Double instead of compiler referring to type of assigned value.
let variable = 23 as Double
This is called type casting .As per definition in Swift,
Type casting in Swift is implemented with the is and as operators.
These two operators provide a simple and expressive way to check the
type of a value or cast a value to a different type.
So these are not different in terms of functionality. Using first way, we are adding redundant token for declaring a constant as type inference would detect type automatically by value.
By Second way, we are forcing a constant to have a kind of value which would be useful in case of superClass/Subclass type casting.

Ambiguous use of 'init' with CFStringTransform and Swift 3

When trying to build the sample project of BonMot,
let theCFMutableString = NSMutableString(string: myString) as CFMutableString
CFStringTransform(theCFMutableString, UnsafeMutablePointer<CFRange>(nil), kCFStringTransformToUnicodeName, false)
I get this error on the CFStringTransform line
Ambiguous use of 'init'
The Xcode 8 project uses Swift 3
In Swift 2, pointer types conformed to NilLiteralConvertible, allowing a non-optional pointer type to represent a null pointer. Therefore when you did
UnsafeMutablePointer<CFRange>(nil)
the compiler was actually using the init(_ other: COpaquePointer) initialiser of UnsafeMutablePointer, as COpaquePointer is NilLiteralConvertible and can therefore represent a null pointer.
However in Swift 3 (SE-0055), pointer types no longer conform to ExpressibleByNilLiteral. Rather than allowing a non-optional pointer type to represent a null pointer, this is now simply done with optionals, where nil means a null pointer.
Therefore you can just pass nil directly into the range parameter of CFStringTransform, as it expects a UnsafeMutablePointer<CFRange>!:
CFStringTransform(theCFMutableString, nil, kCFStringTransformToUnicodeName, false)

Optional properties in optional classes VS Optional values in optional dictionaries

I noticed some interesting behavior when trying to access values of optional properties in optional classes VS trying to access the values of optional values in optional dictionaires.
It seems that in the former case you only need to unwrap once to access the value. However, in the latter case you have to unwrap twice to access the value. I was wondering why this is, and was hoping someone could provide me with some insight!
Below is an example accessing the value of an optional property in an optional class
class Cat{
var food : Food?
}
class Food{
var amount : Int?
}
var meowzer = Cat()
meowzer.food = Food()
meowzer.food?.amount = 10
var catFoodAmt = meowzer.food?.amount
print("\(catFoodAmt)")
if let catFoodCount = meowzer.food?.amount{
print("\(catFoodCount)")
}
The result of the first print statement is:
Optional(10)
The result of the second print statement (after unwrapping) is:
10
Below is an example of accessing the value of an optional value in an optional dictionary
var dog : [String : Int?]?
dog = ["treat_count" : 10]
var dogTreatAmt = dog?["treat_count"]
print("\(dogTreatAmt)")
if let dogTreatCount = dog?["treat_count"] , dogTreatCountFinal = dogTreatCount{
print("\(dogTreatCount)")
print("\(dogTreatCountFinal)")
}
The result of the first print statement is:
Optional(Optional(10))
The result of the second print statement (after unwrapping once) is:
Optional(10)
The result of the third print statement (after unwrapping twice) is:
10
Why do I need to unwrap twice to access the desired value in the second case but not the first?
My guess is it has to do with that fact that if I were to have used a key other than "treat_count" (like "count" for example) then the value for that key would have been nil. However, I haven't been able to find a iOS "rule" or a better explanation on why this is. Any help would be much appreciated.
The difference is that Cat.food?.amount returns Int? while Dictionary<String, Int?>.subscript(String) returns Int??.
This is because Dictionary.subscript<Key> returns Element?, and Element here is Int?. Thus you're getting one extra level of Optional.
Optional chaining just removes an extra Optional wrapping at the point that it's used. It doesn't collapse all Optionals. In one case you have two, collapsed to 1 (for one ?) and in the second you have three, collapsed to 2 (for one ?).
As vadian suggests, this would be a crazy Dictionary, so it's unlikely to come up in good Swift, but it can be reasoned about. If it weren't like this, you would lose information.
It actually makes sense : simply count the number of ?s :).
With you first example, the property is an optional where, in your second example, you have an optional dictionary where its key is a string and the value is an optional integer.
So if you want to access the value of the second example, you have to unwrap the dictionary, then unwrap whatever there is in that dictionary for a given key.
This is a good question. Let's think the type definition of a Dictionary:
struct Dictionary<Key : Hashable, Value>
And the signature of the subscript function:
public subscript (key: Key) -> Value?
Which can also be thought of as:
public subscript (key: Key) -> Optional<Value>
Armed with this, let's look at your dictionary, which is typed as:
Dictionary<String, Int?>
Or more explicitly
Dictionary<String, Optional<Int>>
Where Value is of type Optional<Int>, and Key is of type String
So if we substitute in the key, the subscript definition is:
subscript (key: String) -> Optional<Value>
And if we substitute it in the Value, we get what you are seeing:
subscript (key: String) -> Optional<Optional<Int>
Now, let's break down your code and to make everything fit together:
var dogTreatAmt = dog?["treat_count"]
Since dog is optional, no matter what you call on it, the result will also be wrapped in an Optional, which we will temporarily think of as Optional(FunctionReturn)
Now let's take a look at FunctionReturn, which is the subscript function. We have already determined that this will return Optional<Optional<Int>>
Which means that really you're returning Optional<Optional<Optional<Int>>>, however as noted by Rob Napier,
"Optional chaining removes an extra Optional wrapping at the point that it's used".

What does :?> mean in f#?

Given the line:
let win = XamlReader.Parse(xaml) :?> Window
What is :?> doing?
I tried looking up ternary but not noticing the :?, it seems to be for type testing?. Also I know > is piping but Window does not have any constructor parameters.
It is the dynamic cast operator which has nothing to do with piping. I quote MSDN section on downcasting:
The :?> operator performs a dynamic cast, which means that the success
of the cast is determined at run time. A cast that uses the :?>
operator is not checked at compile time; but at run time, an attempt
is made to cast to the specified type. If the object is compatible
with the target type, the cast succeeds. If the object is not
compatible with the target type, the runtime raises an
InvalidCastException.

Resources