Using Xojo 2023r1, why would this code not yield an error during Compile time?
Var myDict As New Dictionary
myDict.Value("de") = "Deutsch"
myDict.Value("en") = "English"
myDict.Value("fr") = "Français"
For Each key As String In myDict
ListBox1.AddRow myDict.Value(key).StringValue
Next
As you may have spotted, I accidentally looped over a Dictionary (instead of using its Keys method).
A Dictionary is neither a String array not does it implement the Iterable interface. In my opinion, this should yield a “This object does not implement the Iterable interface and cannot be used in a For Each loop” error during compile time.
Dictionaries are iteratable BUT their items aren’t strings, they are DictionaryEntry objects
In your example the compiler should point out the incompatibility in the “key” declaration as String instead of the expected DictionaryEntry. Compiling it and raising a crazy exception later is an issue needing a report.
Var myDict As New Dictionary
myDict.Value("de") = "Deutsch"
myDict.Value("en") = "English"
myDict.Value("fr") = "Français"
For Each entry As DictionaryEntry In myDict
System.DebugLog entry.Value
Next
---
Run:
08:28:10 : test Launched
08:28:11 : Deutsch
English
Français
Then I correct my assumption in that Xojo should yield a “Type mismatch” compile time error, since a DictionaryEntry (which I didn’t even realize existed) is not assignable to a String.
I’m a little sad that, given the Documentation and the lack of a compile-time error (and since I was working inside a web app, I didn’t even see the Runtime error which made me spend a lot of time bug hunting), I was not able to infer that.
The documentation is unsurprisingly bad regarding this feature:
In “For Each … Next” there is no mention and no example at all.
The docs are always needing improvements. There are lots of hidden features that could be better documented, sometimes in more than one place as a cross-reference citation.
It’s a different construct using keys, they can for sure be variants, but it’s unnecessary and less performant then directly using strings if the keys are strings:
Var myDict As New Dictionary
myDict.Value("de") = "Deutsch"
myDict.Value("en") = "English"
myDict.Value("fr") = "Français"
For Each key As String In myDict.Keys
System.DebugLog key + " : " + myDict.Value(key)
Next
System.DebugLog "---"
For Each entry As DictionaryEntry In myDict
System.DebugLog entry.Key + " : " + entry.Value
Next