Binary operator '&&' cannot be applied to two 'Int' operands - swift

I wanted to check for below values firstName and lastName. But Swift will not allowing me to access. It is giving error like "Binary operator '&&' cannot be applied to two 'Int' operands".
if firstName.length && lastName.length {
}

In Swift you cannot check for non-null like in C and Objective-C, you have to write
if firstName.length > 0 && lastName.length > 0 { }

#Vadian has a good answer, but it could be put more clearly — and there's an extra wrinkle:
For things like logic operators (&& and ||) and the conditions of if and while statements, C accepts any type -- it just treats any zero value (which includes null pointers, but your string length here is just a zero integer) as false, and anything else as true.
In Swift, though, the only type allowed in such Boolean logic contexts is Bool — you can't pass an integer and expect to branch on whether the value is zero, so you have to use a comparison operator like > or ==, or a property or method that returns a Bool value.
Since you're dealing with Strings, you'd do best to use the isEmpty property anyway. Getting the length of a Swift String is not a "free" computation — the same number of bytes could be different numbers of human-readable characters depending on what those bytes are, so you can't count characters without examining bytes. It's a lot faster to answer whether the string is empty than to check all the bytes.
(Then again, maybe you're not using Swift strings anyway? Those don't have the length property you're using.)

Related

What is the most efficient operator to compare any two items?

Frequently I need to convert data from one type to another and then compare them. Some operators will convert to specific types first and this conversion may cause loss of efficiency. For instance, I may have
my $a, $b = 0, "foo"; # initial value
$a = (3,4,5).Set; # re-assign value
$b = open "dataFile"; # re-assign value
if $a eq $b { say "okay"; } # convert to string
if $a == 5 { say "yes"; } # convert to number
if $a == $b {} # error, Cannot resolve caller Numeric(IO::Handle:D: );
The operators "eq" and "==" will convert data to the digestible types first and may slow things down. Will the operators "eqv" and "===" skip converting data types and be more efficient if data to be compared cannot be known in advance (i.e., you absolutely have no clue what you are going to get in advance)?
It's not quite clear to me from the question if you actually want the conversions to happen or not.
Operators like == and eq are really calls to multi subs with names like infix:<==>, and there are many candidates. For example, there's one for (Int, Int), which is selected if we're comparing two Ints. In that case, it knows that it doesn't need to coerce, and will just do the integer comparison.
The eqv and === operators will not coerce; the first thing they do is to check that the values have the same type, and if they don't, they go no further. Make sure to use the correct one depending of if you want snapshot semantics (eqv) or reference semantics (===). Note that the types really must be the exact same, so 1e0 === 1 will not come out true because the one value is a Num and the other an Int.
The auto-coercion behavior of operators like == and eq can be really handy, but from a performance angle it can also be a trap. They coerce, use the result of the coercion for the comparison, and then throw it away. Repeatedly doing comparisons can thus repeatedly trigger coercions. If you have that situation, it makes sense to split the work into two phases: first "parse" the incoming data into the appropriate data types, and then go ahead and do the comparisons.
Finally, in any discussion on efficiency, it's worth noting that the runtime optimizer is good at lifting out duplicate type checks. Thus while in principle, if you read the built-ins source, == might seem cheaper in the case it gets two things have the same type because it isn't enforcing they are precisely the same type, in reality that extra check will get optimized out for === anyway.
Both === and eqv first check whether the operands are of the same type, and will return False if they are not. So at that stage, there is no real difference between them.
The a === b operator is really short for a.WHICH eq b.WHICH. So it would call the .WHICH method on the operands, which could be expensive if an operand is something like a really large Buf.
The a eqv b operator is more complicated in that it has special cased many object comparisons, so in general you cannot say much about it.
In other words: YMMV. And if you're really interested in performance, benchmark! And be prepared to adapt your code if another way of solving the problem proves more performant.

Precondition failed: Negative count not allowed

Error:
Precondition failed: Negative count not allowed: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/StringLegacy.swift, line 49
Code:
String(repeating: "a", count: -1)
Thinking:
Well, it doesn't make sense repeating some string a negative number of times. Since we have types in Swift, why not use an UInt?
Here we have some documentation about it.
Use UInt only when you specifically need an unsigned integer type with
the same size as the platform’s native word size. If this isn’t the
case, Int is preferred, even when the values to be stored are known to
be nonnegative. A consistent use of Int for integer values aids code
interoperability, avoids the need to convert between different number
types, and matches integer type inference, as described in Type Safety
and Type Inference.
Apple Docs
Ok that Int is preferred, therefore the API is just following the rules, but why the Strings API is designed like that? Why this constructor is not private and the a public one with UInt ro something like that? Is there a "real" reason? It this some "undefined behavior" kind of thing?
Also: https://forums.developer.apple.com/thread/98594
This isn't undefined behavior — in fact, a precondition indicates the exact opposite: an explicit check was made to ensure that the given count is positive.
As to why the parameter is an Int and not a UInt — this is a consequence of two decisions made early in the design of Swift:
Unlike C and Objective-C, Swift does not allow implicit (or even explicit) casting between integer types. You cannot pass an Int to function which takes a UInt, and vice versa, nor will the following cast succeed: myInt as? UInt. Swift's preferred method of converting is using initializers: UInt(myInt)
Since Ints are more generally applicable than UInts, they would be the preferred integer type
As such, since converting between Ints and UInts can be cumbersome and verbose, the easiest way to interoperate between the largest number of APIs is to write them all in terms of the common integer currency type: Int. As the docs you quote mention, this "aids code interoperability, avoids the need to convert between different number types, and matches integer type inference"; trapping at runtime on invalid input is a tradeoff of this decision.
In fact, Int is so strongly ingrained in Swift that when Apple framework interfaces are imported into Swift from Objective-C, NSUInteger parameters and return types are converted to Int and not UInt, for significantly easier interoperability.

Comparing Int and nil in swift [duplicate]

This is valid code in Swift:
println(nil < 1)
And the output will be true, likewise
println(nil > 1)
will be false (the number 1 is arbitrary, you can do the same for -1 and probably something else). The reason I ask is because I saw some code that tried to compare "some_string".toInt() to a numeric value and it compiled, which seems wrong considering toInt() returns Int?.
My question is, should this be valid syntax in Swift? If so, what is the numeric value of nil?
Swift 3.0 Update:
Looks like Swift Evolution tackled this issue by removing the optional comparison operators. This is no longer an issue in Swift 3.0 as it doesn't compile.
I believe what is happening is that the literal 1 is being implicitly typecast to the Int? type by the comparison to nil. For those who aren't used to Swift, I'll explain a little further. Swift has a concept called "optionals", which can either have a value or be nil. (For anyone familiar with Haskell, this is basically the Maybe monad.) It's illegal to assign nil to a variable that wasn't explicitly defined as optional, so let i: Int = nil will be rejected by the compiler. This allows for several benefits which are out of the scope of this answer, and it's a rather clever way to do it.
What's happening here, though, is that the literal 1 is a valid value of several types: Int, Int32, Int64, UInt32, UInt64, etc., etc., etc. And it's also a valid value of the optional versions of those types: Int?, Int32?, etc.
So when the Swift compiler sees a comparison between a literal value and nil, it tries to find a type that both these values would be valid for. 1 is a valid value of the Int? type, and nil is also a valid value of the Int? type, so it applies the comparison operator with the type signature (Int?, Int?) -> Bool. (That's the comparison operator that takes two Int? values and returns a Bool). That operator's rules say that nil values sort lower than anything else, even Int.min, and so you get the result seen in the OP's question.

What is type of 123_456_789?

I see in Swift examples values like 123_456_789, numbers with underscores. What type do these values have by default?
Does it depend on the type of the variable I assign them to? They look quite funny and new to me, so I wonder, how are they treated if they are thrown just like they are, without defining a type?
From the documentation
(The Swift Programming Language -> Language Guide -> The Basics
-> Numeric Literals):
Numeric literals can contain extra formatting to make them easier to
read. Both integers and floats can be padded with extra zeros and can
contain underscores to help with readability. Neither type of
formatting affects the underlying value of the literal:
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
So your 123_456_789 is a integer literal, and identical to 123456789.
You can insert the underscores wherever you want, not only as a
"thousands separator", such as 1_2_3_4_5_6_7_8_9 or 1_23_4567_89, if you like to write obfuscated code.
123_456_789 is an "integer literal" just like 123456789. "integer literal" is a type separate from Int or Int32 or Int8 or whatever. An "integer literal" can be assigned to any integer type (unlike for example an Int value which can only be assigned to an Int).
If you ask "can I treat them as integers", that doesn't make sense. It's a different type. For every type there are rules how it can be used. The rules for Int and "integer literal" are different.

! vs == nil in objective-c [duplicate]

This question already has answers here:
Testing for nil in Objective-C -- if(x != nil) vs if(x)
(4 answers)
Closed 9 years ago.
If you have an object like NSString *someString, what is the difference, if any, between
if (!someString)
vs
if (someString == nil)
Thanks!
The first syntax you use:
if (!someString)
exploits a sort of "ambiguity" of C deriving from the fact that the original standard of C lacked a proper boolean type. Therefore, any integer value equalling 0 was interpreted as "false", and any integer value different from "0" was taken as "true". The meaning of ! is therefore defined based on this convention and current versions of the C standard have kept the original definition for compatibility.
In your specific case, someString is a pointer, so it is first converted to an integer, then ! someString is interpreted as a bool value of true when someString points at the location 0x000000, otherwise it evals to "true".
This is fine in most conditions (I would say always), but in theory, NULL/nil could be different from 0x000000 under certain compilers, so (in very theory) it would be better to use the second syntax, which is more explicit:
if (someString == nil)
It is anyway more readable and since someString is not an integer (rather a pointer), IMO, better practice in general.
EDIT: about the definition of NULL...
Whether the C standard defines NULL to be 0 is an interesting topic for me...
According to C99 standard, section 7.17, "Common definitions ":
NULL [which] expands to an implementation-defined null pointer constant;
So, NULL is defined in stddef.h to an implementation-defined null pointer constant...
The same document on page 47 states:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
So, the null pointer constant (which is (void*)0) can be converted to a null pointer and this is guaranteed to compare unequal to a pointer to any object or function.
So, I think that basically it depends on whether the implementation decides that the result of converting a null pointer constant to a null pointer produces a pointer which converted back to an integer gives 0. It is not clear that a null pointer interpreted as an integer equals 0.
I would say that the standard really try and enforce the null pointer being 0, but leaves the door open to systems where the null pointer was not 0.
For most pointers, they're equivalent, though most coders I know prefer the former as it's more concise.
For weakly linked symbols, the former resolves the symbol (and will cause a crash if it's missing) while an explicit comparison against nil or NULL will not.
The bang, exclamation, ! prefix operator in C is a logical not. At least, its a version of it. If you looked at a typical logical not truth table you would see something like this:
Input Result
1 0
0 1
However in C the logical not operator does something more like this:
Input Result
non-zero 0
0 1
So when you consider that both NULL and nil in Objective-C evaluate to 0, you know that the logical not operator applied to them will result in a 1.
Now, consider the equality == operator. It compares the value of two items and returns 1 if they are equal, 0 if they are not. If you mapped its results to a truth table then it would look exactly like the results for logical not.
In C and Objective-C programs, conditionality is actually determined by int's, as opposed to real booleans. This is because there is no such thing as a boolean data type in C. So writing something like this works perfectly fine in C:
if(5) printf("hello\n"); // prints hello
and in addition
if(2029) printf("hello\n"); // also prints hello
Basically, any non-zero int will evaluate as 'true' in C. You combine that with the truth tables for logical negation and equality, and you quickly realize that:
(! someString) and (someString == nil)
are for all intents identical!
So the next logical question is, why prefer one form over another? From a pure C view-point it would be mostly a point of style, but most (good) developers would choose the equality test for a number of reasons:
It's closer to what you are trying to express in code. You are
trying to check if the someString variable is nil.
It's more portable. Languages like Java have a real boolean type.
You cannot use bang notation on their variables or their NULL
definition. Using equality where its needed makes it easier to port
C to such languages later on.
Apple may change the definition of nil. Ok, no they won't! But it
never hurts to be safe!
In your case it means the same thing. Any pointer that does not point to nil will return YES (true).
Normally the exclamation mark operator negates a BOOL value.
If you mean to test the condition "foo is nil" you should say that: foo == nil.
If you mean to test a boolean value for falsehood, !foo is okay, but personally I think that a skinny little exclamation point is easy to miss, so I prefer foo == NO.
Writing good code is about clearly conveying your intention not just to the compiler, but to the next programmer that comes along (possibly a future you). In both cases, the more explicit you can be about what you're trying to do, the better.
All that aside, ! and ==nil have the same effect in all the cases I can think of.
! is a negation operator. If your object isn't allocated, you will reach the same result from a truth table as you would with an == nil operation.
But, ! is usually more used for boolean operations.
if(!isFalse) {
//if isFalse == NO, then this operation evaluates to YES (true)
[self doStuff];
}
When you use ! on an object like !something it just checks to see if the pointer is pointing to nil, if it doesn't, it returns true, and the if statement fires.