This question already has answers here:
println dictionary has "Optional"
(2 answers)
Closed 7 years ago.
If the following code runs
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
print(airports["YYZ"])
Why does the console print
Optional("Toronto Pearson")
Why does it print Optional( withValue ) and not just the value?
Why would I need to know that in the console?
Swift has optional types for operations that may fail. An array index like airports["XYZ"] is an example of this. It will fail if the index is not found. This is in lieu of a nil type or exception.
The simplest way to unwrap an optional type is to use an exclamation point, like so: airports["XYZ"]!. This will cause a panic if the value is nil.
Here's some further reading.
You can chain methods on option types in Swift, which will early exit to a nil without calling a method if the lefthand value is nil. It works when you insert a question mark between the value and method like this: airports["XYZ"]?.Method(). Because the value is nil, Method() is never called. This allows you to delay the decision about whether to deal with an optional type, and can clean up your code a bit.
To safely use an optional type without panicking, just provide an alternate path using an if statement.
if let x:String? = airports["XYZ"] {
println(x!)
} else {
println("airport not found")
}
Related
This question already has answers here:
Check if `Any` value is object
(2 answers)
Closed 3 years ago.
Is it possible to check if an object (not as in OOP) is of reference type or value type?
let something : Any = getSomething() // func getSomething() -> Any
let isReferenceType : Bool = // how to check?
EDIT:
As pointed out this is practically a duplicate of Check if `Any` value is object
This is not so easy as it seems, see
let isReferenceType: Bool = type(of: something) is AnyClass
See How to test whether generic variable is of type AnyObject
However, if you need such things, then usually you have some big problem with your architecture that you should address instead. Using Any type should be the last resort for exceptional situations.
This question already has an answer here:
Swift 3 incorrect string interpolation with implicitly unwrapped Optionals
(1 answer)
Closed 6 years ago.
I don't understand why the type system lets me do this?
In other words I would expect this to crash when foo is passed to the function.
var foo:String!
func someFunction(_ bar:String?) {
print("-- \(bar) --")
}
someFunction(foo)
=> writes "-- nil --"
As #Hamish so correctly points out here:
https://stackoverflow.com/a/39537558/308189
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.
And the comment on the answer explains why this question was asked:
As if it weren't bad enough that you have to use an IUO, now they're less useful and behave contradictorily. If I use one it's because I want it to be implicitly unwrapped. They should be called Schrödinger Optionals from now on. – Andreas
Inside your someFunction you are printing the optional not String. that's why it is not crashing. if you want to print bar as String you have to unwrap the value.
// This line will create variable named foo and type of it will be String! and value of it will be nil.
// It mean i can access this variable is force-wraped so it may dangerous but uses of this variable without type checking compiler will not give any warning(ignore by compiler).
var foo:String!
// This function will accept `String` value or `nil`.
func someFunction(_ bar:String?) {
print("-- \(bar) --")
}
// So calling this function use of `foo`(valued nil) will not give any compiler issue.
someFunction(foo)
This question already has answers here:
How is Swift `if let` evaluated?
(5 answers)
Closed 7 years ago.
While reading the official Apple Guide I found this
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
greeting = "Hello \(name)"
}
There is a constant declaration and assignment where I — as a beginner — expected an expression returning a boolean. But the condition of this if statement seems to get true as the value, because the code inside the parentheses is being executed.
Does the initialization of a constant return a boolean value or something that a if statement can use as a condition?
This is called Optional Binding. Quoting from the Basics -> Optionals -> Optional Binding section of the Swift Language Guide.
You use optional binding to find out whether an optional contains a
value, and if so, to make that value available as a temporary constant
or variable. Optional binding can be used with if and while statements
to check for a value inside an optional, and to extract that value
into a constant or variable, as part of a single action.
What this if let construct is doing is checking if someOptional is exists. If it isn't nil/.None then it "binds" the Optional value to a constant.
if let constantName = someOptional {
...
}
This can be thought of as:
if someOptional != nil {
let constantName = someOptional!
....
}
This question already has an answer here:
Swift Optionals - Different ways of unwrapping
(1 answer)
Closed 8 years ago.
When dealing with an optional in Swift, there are two different ways to access the value behind the optional if it exists. You can do a manual check:
if someOptional != nil {
doSomethingWithValue(someOptional!)
}
else {
//handle nil...
}
or, you can use an if let block to unwrap the optional automatically:
if let unwrapped = someOptional {
doSomethingWithValue(unwrapped)
}
else {
//handle nil...
}
Is one of these options preferable to the other for any reason? Which, if either, is more idiomatic?
EDIT: In response to the close votes, I'm attempting to ask if there is a reason to use one over the other for any reason other than preference, whether it is for performance reasons, safety reasons, or something else.
I think you missed one line of code in your "manual check": Before checking
if someOptional != nil
you'd rather had to assign by something like:
someOptinal : <TypeOptional>? = anyFunctionThatProvidesAnOptional
And therefore this is my opinion: The second way (the so called "optional binding") combines that two lines in one line, so it is shorter and therefore better way.
This question already has answers here:
What does an exclamation mark mean in the Swift language?
(23 answers)
Swift variable decorations with "?" (question mark) and "!" (exclamation mark)
(1 answer)
Closed 8 years ago.
There are three way to declare a property in Swift:
var optStr: String?
var normStr: String = "normStr"
var exactStr: String!
The first one is property with an optional type, a type that can contain either nil or the String in our case. The second one is a property that always contain the String. It should be initialized in init or in the declaration.
But what about the third way?
var exactStr: String!
I made some experiments in the playground, and it turned out that a function that takes type? can take both type, type? and type! variables as an argument:
var optStr: String?
var normStr: String
var forcedStr: String!
func printStr(str: String?) {
println("str: \(str)")
}
printStr(optStr) //prints: "str: nil"
//printStr(normStr) //doesn't compile as not initialized
printStr(forcedStr) //prints: "str: nil"
optStr = "optStr"; normStr = "normStr"; forcedStr = "forcedStr"
printStr(optStr) //prints "str: optStr"
printStr(normStr) //prints "str: normStr"
printStr(forcedStr) //prints "str: forcedStr"
So why and when should I use type!?
Update: this is not a duplicate of What does an exclamation mark mean in the Swift language?. I'm not asking about unwrapping a variable: I'm asking about declaring a property with an exclamation point (Type!).
It's a variable of type "implicitly-unwrapped optional String". Essentially, every access of implicitStr is treated as if it were written implicitStr! (thus unwrapping the value).
This, of course, will cause a crash if the value is nil. You can still test the implicit optional via if implicitStr != nil, or use it in optional chaining as var foo = implicitStr?.uppercaseString. So you can still use it just as safely as a normal optional; it's just biased toward the case where the value is not nil.
Implicitly-unwrapped optionals are quite useful in cases where the value may not be present at initialization, but are set early and unlikely to become nil again. (For example, a variable you set in -awakeFromNib might reasonably be an implicitly-unwrapped optional.)
Further, since Objective-C methods can return both nil and object types, their return values cannot be modeled as non-optional. To avoid requiring liberal use of forced unwrapping whenever dealing with Cocoa APIs, though, the parameters and return types of Cocoa APIs are usually represented as implicitly-unwrapped optionals.