I'm trying to set a string to be different things depending on an int, but when I declare a string in any if statement, even an always true one it seems to give me error: 'correctColor' undeclared (first use in this function).
If I have this line by itself, my code works fine.
char correctColor[] = "red";
But if I have something like
bool test = true;
if(test){
char correctColor[] = "red";
}
it gives me the error above. Any help is greatly appreciated.
Please see the comments below
bool test = true;
if(test){
char correctColor[] = "red";
// correctColor is available here until the end brace
}
// correctColor is not available here - it is now out of scope
Consider if test is false - Then correctColor would not be declared!
Related
Consider the following code:
const testArray = ['string1', 'string2', 'string3'];
for (let iterator in testArray) {
console.log(iterator == 0);
}
My IDE (Visual Studio Code), complains about the console.log, that it will always return false (error: ts(2367))
But if I input this code directly either here, or in a JSBin, or in my current browser, I always get the true result on the first iteration. Anyone can explain me, if my IDE is to blame for this, or maybe there is some legacy javascript, where that condition indeed always returns false?
Based on this table https://dorey.github.io/JavaScript-Equality-Table/ it also seems that the above code is valid, and will run as expected.
const testArray = ['string1', 'string2', 'string3'];
for (let iterator in testArray) {
console.log(iterator == 0);
}
Overview
I am new to the Swift language, but not others, and am having trouble executing a simple Array.filter statement that I would like to return as the result for a function in a class I am writing, but it seems adding the return keywords causes non-intuitive compile errors.
Question: Does anyone know what to make of these error messages, and how to fix them?
Samples
Declarations
var arrDictIVar = [["dictVar1": "value"]]
...
func someFunc(var1: String) {...
Various Trials
Set 1
return arrDictIVar.filter({
$0["dictVar1"] == var1
})
return arrDictIVar.filter(){
$0["dictVar1"] == var1
}
return arrDictIVar.filter{
$0["dictVar1"] == var1
}
Error: Cannot invoke 'filter' with an argument list of type '(#noescape ([String : String]) throws -> Bool)'
Error Subtext: Expected an argument list of type '(#noescape (Self.Generator.Element) throws -> Bool)'
Source: Sample MCVE Execute here
Set 2
return arrDictIVar.filter({
$0["dictVar1"] == var1
})[0]
return arrDictIVar.filter() {
$0["dictVar1"] == var1
}[0]
return arrDictIVar.filter{
$0["dictVar1"] == var1
}[0]
Error: Cannot subscript a value of type '[[String : String]]'
Source: Sample MCVE Execute here
Set 3
arrDictIVar.filter({
$0["dictVar1"] == var1
})
arrDictIVar.filter(){
$0["dictVar1"] == var1
}
arrDictIVar.filter{
$0["dictVar1"] == var1
}
Warning: Result of call to 'filter' is unused
Note: Just to show that the block is properly formed without the return keyword.
Source: Sample MCVE (Execute here)
Other Information
I have also tried modifying the IVar declaration to var arrDictIVar: Array<Dictionary<String,String>> = [..., and the function declaration to func someFunc(var1: String) -> Dictionary<String,String>{... at various times, with similar failures.
Edit: I had posted an answer at the same time of this question as I found a combination that worked towards nearing the end of this posting. It does include changing the return data type in the method signature, along with giving other information alluding to the inaccurate, or at least confusing nature, of the compiler, and the error messages it presents.
After this I was left with a follow-up question:
If anyone would be able to explain why this was happening, and give a clear judgement as the compiler error message was not as helpful as it could be, my reading/interpretation of the error message was not as clear as it could have been, potentially saving time by changing my mindset somehow, or either, please comment on that note.
Victor Sigler's answer does seem to cover this in some good detail.
Let's explain in detail every set you have put in your question:
Set 1:
Your three examples are right in code and are the same to the compiler, you're using a trailing closure and the parentheses can be omitted.
Sometimes the compiler(because it's so young yet!!!) not show the exactly error happening in your code, but definitely in this step you're using the filter function to return an [[String: String]] or an array of dictionaries and you're missing the type of the return of the function, it's assumed by the compiler as Void.
About #noescape:
Adding #noescape guarantees that the closure will not be stored somewhere, used at a later time, or used asynchronously. Remember that closures capture values.
You can read more about the #noescape clause in the following two very good tutorials:
#noescape Attribute
Hipster Swift: Demystifying the Mysterious — KrakenDev
So to resume it, if you change your function to the following it should work:
func someFunc(var1: String) -> [[String: String]] {
return arrDictIVar.filter({
$0["dictVar1"] == var1
})
}
Set 2:
If you fix the error in the Set 1 then when you code:
return arrDictIVar.filter{
$0["dictVar1"] == var1
}[0]
You're trying to return a [String: String] or a dictionary and it's wrong regarding the return type of the function it's [[String: String]].
But be careful because if you change the return type to [String: String] and try to index the array returned for the filter function and there is nothing founded by the filter function you would get an runtime error.
Set 3
I think it is the more easy to understand because as the warning said, the filter function returns a new list of elements and if you don't save it or returned in your function it's unused, something like this:
func someFunc(var1: String){
arrDictIVar.filter({
$0["dictVar1"] == var1
})
}
I hope this help you.
I have the following code:
public fun findSomeLikeThis(): ArrayList<T>? {
val result = Db4o.objectContainer()!!.queryByExample<T>(this as T) as Collection<T>
if (result == null) return null
return ArrayList(result)
}
If I call this like:
var list : ArrayList<Person>? = p1.findSomeLikeThis()
for (p2 in list) {
p2.delete()
p2.commit()
}
It would give me the error:
For-loop range must have an 'iterator()' method
Am I missing something here?
Your ArrayList is of nullable type. So, you have to resolve this. There are several options:
for (p2 in list.orEmpty()) { ... }
or
list?.let {
for (p2 in it) {
}
}
or you can just return an empty list
public fun findSomeLikeThis(): List<T> //Do you need mutable ArrayList here?
= (Db4o.objectContainer()!!.queryByExample<T>(this as T) as Collection<T>)?.toList().orEmpty()
try
for(p2 in 0 until list.count()) {
...
...
}
I also face this problem when I loop on some thing it is not an array.
Example
fun maximum(prices: Array<Int>){
val sortedPrices = prices.sort()
for(price in sortedPrices){ // it will display for-loop range must have iterator here (because `prices.sort` don't return Unit not Array)
}
}
This is different case to this question but hope it help
This can also happen in Android when you read from shared preferences and are getting a (potentially) nullable iterable object back like StringSet. Even when you provide a default, the compiler is not able to determine that the returned value will never actually be null. The only way I've found around this is by asserting that the returned expression is not null using !! operator, like this:
val prefs = PreferenceManager.getDefaultSharedPreferences(appContext)
val searches = prefs.getStringSet("saved_searches", setOf())!!
for (search in searches){
...
}
I am new to making mobile substrate tweaks and I wanted to hook this function but having a bit of trouble.
%hook classname
- (void)function:(BOOL) {
%orig;
return TRUE;
}
%end
but when i try to MAKE this it gives me an error. void function should not return a value.
I just want to change the BOOL to always return true.
Thanks.
Your aim is vague a bit. The error is because your function header is
- (void)function:(BOOL) foo {
%orig;
return YES;
}
This means function function has a boolean argument and RETURNS NOTHING. So you can't write return YES in your function. This line causes the error.
If your goal is to return the value of the original function with YES argument no matter what foo is, you have to rewrite your function like below:
- (void)function:(BOOL) foo {
%orig(YES);
}
I have a class method that is supposed to take an object and populate a few values in place. This is at the stage of functional demonstration, so the implementation will be better later. right now I just would like this to work.
In the code below, the districtID integer is successfully passed to the if statements. The rgb double array does not make it into the if statement scope. The values set at initialization make it all the way to the districtPoint.color without getting set inside the if statement.
the code below will not compile as is. I would like to know how to get the rgb variable to be visible within the if statement scope.
(note: I tried the naive solution of initializing the variables within the if statement. This clears the error, but doesn't let the new rgb variables out of the if scope)
// This method populates properties
+(void)setContantPropertiesForID:(DistrictPoint *)districtPoint
{
int districtID = [districtPoint.districtID intValue];
double rgb[3] = {0,0,0};
if (districtID == 1) {
districtPoint.title = #"District 1";
rgb = {1.0,0.0,0.0}; // error is expected expression
} else if (districtID == 2) {
districtPoint.title = #"District 1";
rgb = {0.0,1.0,0.0};
} else if (districtID == 3) {
districtPoint.title = #"District 1";
rgb = {0.0,0.0,1.0};
} else {
districtPoint.title = nil;
rgb = {1.0,1.0,1.0}; // error condition
}
districtPoint.color = [UIColor colorWithRed:rgb[0] green:rgb[1] blue:rgb[2] alpha:0.5];
}
This has nothing to do with the if statement. You can use the curly-braces notation to set an array's elements only when initializing (as you do, in fact, earlier in the code).