I have an int value defined in one of my method:
int value = [self someMethodThatGetsAnINT];
Later on I have some "ifs" that check upon this value.
How to I express: if (value == nil)?
When I try do this intuitive code writing I get a warning saying:
Semantic Issue: Comparison between pointer and integer ('int' and 'void *')
nil is just a 0 :) Try this :
if (0 == value)
However, why would you be testing nil against an int - something sounds funny here :)
If you really want a nil value returned, you should probably be using NSNumber as your return type instead of int. NSNumber is an class that wraps scalar values in objective-c. You can put an integer in it when you have a valid return value, or return nil when you don't.
you can probably use if (value == (int)nil) but really a function that returns an int shouldn't return nil as nil is not an integer (although it may be represented similarly).
this may help clear it up a little
Related
I've recently came across this question How do I solve the 'Failed assertion: boolean expression must not be null' exception in Flutter
where the problem comes from a should be invalid code that gets treated as valid.
This code can be summarized as :
int stuff;
if (stuff = null) { // = instead of ==
}
But why does this code compiles ? As the following will not.
int stuff;
if (stuff = 42) {
}
With the following compile error :
Conditions must have a static type of 'bool'.
So I'd expect out of consistency that if (stuff = null) to gives the same error.
null is a valid value for a bool variable in Dart, at least until Dart supports non-nullable types.
bool foo = null;
or just
bool foo;
is valid.
Therefore in the first case there is nothing wrong from a statical analysis point of view.
In the 2nd case the type int is inferred because of the assignment, which is known to not be a valid boolean value.
bool foo = 42;
is invalid.
When you say var stuff; with no initial value it is giving stuff a static type of dynamic. Since dyamic might be a bool, it's legal to assign null to a variable of type dynamic, and it's legal to use a possibly null bool in a conditional, the compiler doesn't flag this. When you say int stuff; the compiler knows that stuff could not be a bool. The reported error in that case is cause by the static type of stuff, not the assignment to null.
Edit: Got the real answer from someone who knows how to read the spec.
The static type of an assignment expression is the right hand side of the assignment. So the expression stuff = null has the static type of Null which is assignable to bool.
The reasoning is that the value of an assignment is the right hand side, so it makes sense to also use it's type. This allows expressions like:
int foo;
num bar;
foo = bar = 1;
Commonly assignment operation returns the value that it assigns.
int a = 0;
print(a = 3);//Prints 3
So,
When stuff = null,
'stuff = null' returns null. if statement needs a boolean .null is a sub-Type of boolean.
if(null){}
is valid
When stuff = 42,
'stuff = 42' returns 42. if statement needs a boolean .42 is not a sub-Type of boolean.
if(42){}
is not valid
While converting from Swift 2.3 to 3.2 I received below error.
Error : Binary operator cannot be applied to operands of type Int and String
for this if Condition i.e if (error?.code)! == "-112" which is shown in below line.
if (error?.code)! == "-112"
{
print("hello")
}
Error itself says it's different types Int and String.
You can need to typecast one or another in same form and them compare.
if (String(error?.code)!) == "-112"){
print("hello")
}
Swift is a language with a strong type system. You can compare only values of the same type.
Since the left side is Int anyway use an Int value for the right side. Creating a string is unnecessarily expensive. Don’t do that.
The most efficient (and safe) solution is
if error?.code == -112
{
print("hello")
}
You need to type-cast your error code result to a string, like so:
if String(error?.code)!) == "-112" {
print("Hello")
}
Essentially, you are taking the error?.code, "casting" it as a string by placing it in a string "container mould" and unwrapping the value (retrieving the casted result).
In addition, if you are working with an API response, you have to account for all other error codes in the else/if statement to make sure all responses are handled properly (just in case you are).
I am getting the error message Cannot assign value of type 'String?' to type 'Int'
I have browsed through other questions like this but it still shows the error.
if sunscreenName.text != nil && reapplyTime.text != nil {
sunscreen = sunscreenName.text!
reApplyTime = reapplyTime.text
//Some sort of message such as Progress hud
}
Thanks in advance!
I got your problem, actually what happens here Swift is is type safe langauge
So what you are doing is is to store a String value in Int which will not happen automatically you need to convert it to Int
like this
Int(sunscreenName.text)
But there is a catch there not all string are convertible to Int type, fo e.g.
let name = "roshan"
if you try to convert it to Int it will give you a nil
let a = Int(name)
So its better you do a optional Binding here provided by Swift
if let sunValue = Int(sunscreenName.text),let reApplyValue = Int(reapplyTime.text) {
sunscreen = sunValue
reApplyTime = reApplyValue
}
I recommend reading through The Swift Programming Language to get a better understanding of Swift and its fundamental concepts, since this question is fairly basic.
You make several mistakes:
if sunscreenName.text != nil && reapplyTime.text != nil {
This is wrong. In Swift, if you plan to use the value later, you should use if let rather than comparing to nil. Comparing to nil leaves the values optional, but if let unwraps them. So, do this instead:
if let sunscreenText = sunscreenName.text, let reapplyText = reapplyTime.text {
Now you have the sunscreenText and reapplyText variables, which are typed String, not String? (i.e. they are not optional).
Now, there's these two lines.
sunscreen = sunscreenName.text!
reApplyTime = reapplyTime.text
You don't say which one is giving the error, but the issue is the same in either case. First, use our unwrapped sunscreenText and reapplyText variables instead of sunscreenName.text! and reapplyTime.text. Next, if one of these is meant to be an Int instead of a String, cast it. Swift is not like JavaScript, in that it won't automatically convert values from one type to another, so if something is a string and we need an integer, we have to convert it ourselves.
(assuming reapplyTime was the line that was giving the error:)
if let reapplyInt = Int(reapplyText) {
reapplyTime = reapplyInt
}
The reason we have to unwrap is because Int(String) can return nil if the string is something that can't be converted to an integer. Alternately, we could just provide a default value:
reapplyTime = Int(reapplyText) ?? 0 // sets to 0 if it can't parse the string as an integer
I'm trying to filter Firebase query results with three conditions:
let posts = snapshot.childSnapshots.map {
Post(snapshot: $0)
}.reversed().filter {
post?.isGlobal == dataFilter && (self.dependents.contains($0.postedBy) || self.currentUser?.uid == $0.postedBy)
}
The first condition (post.isglobal == datafilter) must be met. Then, I want to filter posts further when either one of the remaining two conditions are met.
The above code returns an error: Binary operator == cannot be applied to operands of type NSNumber? and Int
Any help would be greatly appreciated.
Thanks!
EDIT: the dataFilter variable is defined as a global variable within the viewcontroller class:
var dataFilter = 0
You can just unwrap your optional post and access its isGlobal intValue property, NSNumber has an intValue property that returns an Int that you can compare against your dataFilter (Int) value. Or use '??' nil coalescing to unwrap your optional binding and at the same time provide a default value for it in case of nil.
So if you unwrap your post object:
post.isGlobal.intValue == dataFilter
Or using the optional biding with the nil coalescing operator:
(post?.isGlobal.intValue ?? 0) == dataFilter
Question regarding Swift 2.1 in Xcode 7.
I have declared an optional variable like this:
var something: Int64?
I would like to later assign it to a dictionary key using a shorthand if, like this:
dictionary['something'] = (something != nil) ? something! : nil
XCode is giving me the following validation error:
Result values in '? :' expression have mismatching types: 'Int64' and
'_'
What is the issue here? Why can't optional Int64 be nil?
There are a number of problems here. First, Int64 isn't an AnyObject. None of the primitive number types are classes. They can be bridged to AnyObject using NSNumber, but you don't get that bridging automatically for Int64 (see MartinR's comment. I originally said this was because it was wrapped in an Optional, but it's actually because it's fixed-width).
Next, this syntax:
(something != nil) ? something! : nil
Is just a very complicated way to say something.
The tool you want is map so that you can take your optional and convert it to a NSNumber if it exists.
dictionary["something"] = something.map(NSNumber.init)
Of course, if at all possible, get rid of the AnyObject. That type is a huge pain and causes a lot of problems. If this were a [String: Int64] you could just:
dictionary["something"] = something
You can't add a Int64 to a dictionary of type [String : AnyObject], you need to wrap in in an NSNumber object. You can only store objects that conform to AnyObject in your dictionary.
var something: Int64?
something = 42
if let myVal: Int64 = something { // unwrap to make sure the value is there
let myNum = NSNumber(longLong: myVal) // create an NSNumber from your Int64
dictionary["something"] = myNum // insert it into the dictionary
}
As Anton Bronnikov said below, if your dictionary was type [String : Int64], you would be able to add your Int64 to it no problem.
It seems that others have already pointed out the issues with the types in your dictionary. I want to add that you can also use the nil coalescing operator '??' as even more concise shorthand for what you are doing in your example. It is most useful when you want to do a check for nil, (and if non-nil) unwrap the value and assign it, otherwise provide a default value.
var maybeSomething: Int?
var dictionary:[String:Int?] = [:]
dictionary["something"] = maybeSomething ?? nil
something! has type Int64. Not optional Int64, but Int64. nil has type nil. You can't have an expression
condition ? Int64 : nil
What would be the type of it?
And the whole thing is pointless. On the right hand side you would have just "something". If that doesn't work then your dictionary doesn't accept optionals.
PS. Noticed that your dictionary wants to store Objective-C objects. In that case, no way it accepts an optional. And it only accepts an Int64 after converting to NSNumber.