I'm trying to understand why casting in the first case works while in the second it fails. What is the difference between the two?
var myVariable = 2
var myDoubleTest1 = Double(myVariable)
var myDoubleTest2 = myVariable as? Double
print(myDoubleTest1) // 2.0
print(myDoubleTest2) // nil
var myDoubleTest1 = Double(myVariable)
This line is just an initializer on Double. It takes an int, and initializes a new double. The documentation is here.
var myDoubleTest2 = myVariable as? Double
The as? keyword in Swift performs a cast. This means, in English, "create a variable named myDoubleTest2. If myVariable is of type Double, then use that. Otherwise, make it nil. We know, from the first line in your code (var myVariable = 2), that myVariable is not a Double (it is an Int), so myDoubleTest2 will be nil. You can read more about type casting here.
The first case
var myDoubleTest1 = Double(myVariable)
you actually converts the Int to Double
but in second
var myDoubleTest2 = myVariable as? Double
it checks whether myVariable is of Double type & has no nil value if passed ,it assigns it's value to myDoubleTest2
Related
var tuples: String! = "subash"
if let goin = tuples {
print(goin!)
}
I am receiving this error:
Cannot force unwrap the value of non-optional type String
I don't what happening constant goin is same as tuples but why it's showing me an error when I do force unwrap
Instead of the above code, this is running well:
var tuples: String! = "subash"
print(tuples!)
But kindly I need a solution to my above problem
That's something normal if you know how optionals work.
Inside the if statement, the right expression must be either Optional or Implicitly Unwrapped Optional, BUT NOT "normal" value.
This is the correct code:
let tuples: String! = "subash"
if let goin = tuples {
print(goin) // NO NEED to unwrap, because going IS NOT Optional
}
The reason this code runs fine:
var tuples: String! = "subash"
print(tuples!)
print(tuples)
... is because tuples is of type Implicitly Unwrapped Optional.
However, in general cases like this:
let myVar: String! = "some string"
if let myNewVar = myVar {
// Some code...
}
... myVar is always an Implicitly Unwrapped Optional, whereas myNewVar is of String type, because of how Optional Unwrapping works with if let statements.
Finally, if we unwrap the value this way:
let myVar: String! = "some string"
if let myVar = myVar {
// Some code...
print(myVar)
}
The printed value is the temp myVar, which is of type String and shadows the Implicitly Unwrapped myVar variable we initially declare.
var a: String = "1"
var b: Int = Int(a)
The example above triggers an error saying that Int needs to be unwrapped.
var a: String = "1"
var b = Int(a)
However if we dismiss the type when declared b and do the same thing, it won't trigger any error.
What is the difference between the two approach? Why the first one needs to be unwrap even though it is not declared as optional?
It is because in first example you are saying that b is of type Int and in second example since you did not make type explicit compiler sets it to Int?.
It is because Int(string) will only work if string can be interpreted as Int, so Int("3")->3 but what should it do if you say Int("text")->nil, because it is not able to parse string into a an Int
You could provide a default value if you wanted in the first example and then it would be OK.
var b: Int = Int(a) ?? 0
How to cast an Any object to a Double. I was able to cast it to a string but I can't find anywhere to cast to a Double. Either read in zip code as a Double or cast zip code after to a Double.
let zipCode = ((o as AnyObject).fieldValue("Zip__c"))!
//String cast that works
lender.First_Name__c = String(describing: zipCode)
The short answer is that you can use as to cast, though you can do this in a few ways. The safe, Swift way of doing it is with optional binding, like this:
if let doubleValue = o as? Double {
print(doubleValue)
}
If you can guarantee it's a Double you can force unwrap it like so:
let doubleValue = o as! Double
I have a simple question, I have this dictionary:
let dict: [String: Any] = ["Area": "100", "YessorNo" : true]
And, for the key area, I want to cast it's value to a double, like so:
let a = dict["Area"] as? Double
When I print a, I get a nil, why? the value 100 is although a string but it is a number isn't? why can't I cast it to a double?
You can't directly cast a String to a Double, you need to use the proper initializer.
guard let numStr = dict["Area"] as? String else {
return
}
let a = Double(numStr)
First, cast from Any to String, and then use an initializer to convert it to Double.
if let a = dict["Area"] as? String, let aDouble = Double(a) {
print(aDouble)
}
Since the other answers provided the code, I will focus on the why of the question. Type casting won't work because, according to the Swift docs, type casting allows you to "treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy." Since a double is not a subclass or a superclass of a string, you can't cast a string to a double even if that string is a string of a number. This is why trying to cast a string to a double returns nil.
Ive searched for the answer to this for a while and can't seem to find it.
But for example, what is the difference here:
var this: that
var this = that
Thanks
var this: That
declares a mutable variable of type That.
var this = that
declares a mutable variabel and assigns an instance of That to it. The type (That) is inferred in this case.
A more belt and braces method of declaring it:
var this: That = that
But usually type inference is enough.
: force assigns a constant/variable a type, whereas = assigns it a value
example of ::
let str: String = ""
example of =:
let str = ""
":" refers to defining the type of the variable
"=" refers to assigning a value to that variable
e.g.
var myString: String (declares a variable of type String)
var myString = "example text" (declares a variable who's type is implicitly determined to be String and assigns the value "example text" to it)
var myString: Int = "example text" (Syntax error. Defined a variable of type Int and tried to assign a String to that value)