Control Statement Violation inside for-loop - ios

I am using SwiftLint in my app. I am getting Control Statement Violation: if, for, guard, switch, while, and catch statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses. (control_statement).
What is wrong with that code? Why i am getting that waring?
Thanks in Advance
for i in 0..<images.count {
if(i == images.endIndex - 1) {
print(i)
}
}

Its simply telling parentheses start ( and parentheses end ) symbols are now not necessary to provide in control statement' conditions so your code will go without () in control statement conditions for example your code will look like below
for i in 0..<images.count {
if i == images.endIndex - 1 {
print(i)
}
}

You have added parentheses in if condition.
Remove it.
for i in 0..<images.count {
if i == images.endIndex - 1 {
print(i)
}
}
You can check detail rule here.

Related

SwiftUI ViewBuilder: is it guaranteed that in `if/ese` statement `else` clause isn't executed when condition is true?

I ask this because I suddenly realized today that, since the if/else statement we use to build View in SwiftUI is interpreted by ViewBuilder, it may behave differently than the plain old if/else statement in Swift language. Could it be that, for some (e.g. performance) reason, SwiftUI pre-execute both clauses and cache the result? Does anyone know it for sure?
I remember I observed some confusing behavior in the past, which might be explained by this hypothesis. But unfortunately I can't recall an example.
The way a result builder transforms your code is spelled out in SE-0289: Result builders. Section “Selection statements” describes how if/else statements are transformed. It gives the following example:
Consider the following code:
if i == 0 {
"0"
} else if i == 1 {
"1"
} else {
generateFibTree(i)
}
Under this pattern, the example code becomes something like the
following:
let vMerged: PartialResult
if i == 0 {
var firstVar = "0"
var firstBlock = BuilderType.buildBlock(firstVar)
vMerged = BuilderType.buildEither(first: firstBlock)
} else if i == 1 {
var secondVar = "1"
var secondBlock = BuilderType.buildBlock(secondVar)
vMerged = BuilderType.buildEither(second:
BuilderType.buildEither(first: secondBlock))
} else {
var elseVar = generateFibTree(i)
var elseBlock = BuilderType.buildBlock(elseVar)
vMerged = BuilderType.buildEither(second:
BuilderType.buildEither(second: elseBlock))
}
You can also read a detailed description of the transformation algorithm, but I think the example makes it clear enough that it will only execute one branch of an if/else statement.

[Clang RecursiveASTVisitor]How to make a distinction between 'If' statement and 'Else If' statement?

I'm using clang's RecursiveASTVisitor to parse some C code. I override visitStmt() and want to make a distinction between 'If' statement and 'Else If' statement.
Example:
if(a > 0){
XXX
}
else if(a == 0){
YYY
}
else{
ZZZ
}
In visitStmt(), I use:
if(isa<IfStmt>(S))
to judge whether a statement is IfStmt.
But how can I know the statement is 'Else If' rather than 'If'?
I want to insert different stubs(XXX under 'If' and YYY under 'Else If').
ps: I'm not a native English speaker. Please forgive me for my poor express.
In C there is not specific else if statement, because
if (a) {
...
}
else if (b) {
...
}
else {
...
}
is conceputally (and in terms of an AST) something like the following
if (a) {
...
}
else {
if (b) {
...
}
else {
...
}
}
So the first snippet is sort of a "hidden nesting", because the body of the first else just consists of a single if ... else statement, so you can omit the {} around it. And the last else does not belong to the first if but to the second.
So what you probably can do to determine whether you have an else if or not, is step up in the tree, and check if the parent node of the current node is an else statement and the if is the first (or only) statement in that parent-else's body.
There are other languages (for instance VB) which have a If .. ElseIf .. Else construct. But C doesn't.

Can't form Range with end < start

While I try to create a for in loop, it gives me an error stating "cant form Range with end < start". Value of i comes 4362626962. How can I fix it?
for i in 1...slashList.count{
let index = slashList[i]
if !quotaList.contains(index+1)
{
slashList.removeAtIndex(index)
}
}
Thank you in advance!
Your for has two problems:
If slashList.count is 0 (because slashList is empty), it would try to count from 1 to 0 adding 1 (which results in an infinite loop), that's why the compiler gives you the error start > end.
if slashList.count is greater than 0 (slashList is not empty), it would use an index which is out of bounds, because you count from 1 to slashList.count, while the indexes go from 0 to slashList.count - 1
to check all indexes it should be:
for i in 0 ..< slashList.count {
// your code
}
to ignore the first element (index 0) do:
for i in 1 ..< slashList.count {
// your code
}
for your special case, it would seem better to me to do something like:
for element in slashList {
if !quotaList.contains(element+1)
{
slashList.removeObject(element)
}
}
You can use removeObject from this answer. If, for some reason, you also need the index, do:
for (index, element) in slashList.enumerate() {
// your code
}
Try with, it should be 0.. not 1...
for i in 0..slashList.count{
let index = slashList[i]
if !quotaList.contains(index)
{
slashList.removeAtIndex(index)
}
}
Why you start loop from index 1 instead 0? If you really need this, you must check if slashList empty array:
if !slashList.isEmpty {
// your code here
}
Also removing items from array you numerating is bad practice. Assume that you want to loop from 0, then there is swifty way to get what you want:
slashList = slashList.enumerate().flatMap{quotaList.contains($0.index + 1) ? $0.element : nil}

What is the difference between a return and a break in an infinite loop?

In doing the Guessing Game from the Rust Book (I won't put the link because it will probably not exist in a few weeks), there is a point where you use return to break out of the loop. I used break instead:
loop {
guess = guesser();
guess_cast = guess.trim().parse();
let guess_num = match guess_cast {
Ok(num) => num,
Err(_) => {
println!("Guess was not a number, try again");
continue;
},
};
if guess_num < answer {
println!("Too low");
} else if guess_num > answer {
println!("Too high");
} else {
println!("You guessed it!");
break;
}
}
Is there a real difference in using return over break in this case? What about other cases when you want to break out of an infinite loop?
If the loop is the final statement in the function, then there is patently no functional distinction between break; and return;. If this condition does not hold, there is evidently a difference, for return terminates execution of the function, while break only terminates execution of the loop.
In the case where they are functionally the same, which you use may vary based on context (which one feels better in this particular location), personal preference and what, if anything, you ate for breakfast.

How to mute jslint error on do{}while(false)

In this simple code:
do {
console.log('o');
} while (false);
jslint produces a warning on the last line saying Unexpected 'false'
I understand why, but I still want to mute it because in these cases that's how I want to have the control flow.
Let's look at what jslint expects in the while statement. From the source:
labeled_stmt('while', function () {
one_space();
var paren = next_token;
funct.loopage += 1;
advance('(');
step_in('control');
no_space();
edge();
this.arity = 'statement';
this.first = expected_relation(expression(0));
if (this.first.id !== 'true') {
expected_condition(this.first, 'unexpected_a');
}
no_space();
step_out(')', paren);
one_space();
this.block = block('while');
if (this.block.disrupt) {
prev_token.warn('strange_loop');
}
funct.loopage -= 1;
return this;
});
It mostly reads like English. 'while', one space, (, no space, expected expression, no space, ).
So let's look at what an expression(0) is. You can read through the source if you're really interested, but to be honest I can't really wrap my head around it either. Sorry. https://github.com/douglascrockford/JSLint/blob/master/jslint.js
As far as I can tell, though, expression(0) traverses the tree of operators and operands, and looks for values with a Right Binding Power greater than 0? And false has a binding power of 0? But variables and comparisons are okay here. I have no clue how that even works. Ask Crockford.
As for shutting up jslint, here is my suggestion:
/*jslint devel: true, continue: true */
var i = 0;
var forever = false;
do {
i = i + 1;
if (i < 5) {
continue;
}
console.log('o');
} while (forever);

Resources