Can I do this when I define an enum? - ios

Can I do this when I define an enum? I mean have a specific entry at the end with a value that is not the expected one?
typedef NS_ENUM(NSInteger, countries) {
kAustria = 101,
kBelgium,
kEngland,
kFrance,
kNONE = 200,
};
This enum will assign 101, 102, 103 and 104 to the four countries respectively and 200 to kNONE, that is what I want, right?
Will this work correctly?
and what about this? (just checking to see the possibilities)
typedef NS_ENUM(NSInteger, countries) {
kAustria = 101,
kBelgium,
kNONE = 200,
kEngland = 103,
kFrance,
};

That's not a problem at all -
you can define specific values for individual constants in the enum definition.
Mixing specific and auto-generated values (i.e. the continuation the compiler will generate for you if you don't explicitly specify a value) will work just fine as well.
Here's a nice blog article explaining enums:
Objective C Enum: How to Declare and Use Enumerated Types in Objective C

Related

Dart firstWhere orElse: generic function return type

The code below defines a generic myFirstWhereFunction with 3 arguments:
Generic list
Generic value to search in the list
Generic default value to return if the searched value is not in the passed generic list
The code:
void main() {
const List<int> intLst = [1, 2, 3, 4];
print(myFirstWhereFunc(intLst, 4, -1));
print(myFirstWhereFunc(intLst, 5, -1));
const List<String> strLst = ['coucou', 'go', 'bold', 'tooltip'];
print(myFirstWhereFunc(strLst, 'go', 'not exist'));
print(myFirstWhereFunc(strLst, 'ok', 'not exist'));
}
T myFirstWhereFunc<T>(List<T> lst, T searchVal, T defaultVal) {
return lst.firstWhere((element) => element == searchVal, orElse: <T> () {
return defaultVal;
});
}
But this code generates an exception.
One solution is to replace the generic myFirstWhereFunc return type by dynamic (code below):
dynamic myFirstWhereFunc<T>(List<T> lst, T searchVal, T defaultVal) {
return lst.firstWhere((element) => element == searchVal,
orElse: () => defaultVal);
}
But is there another way of solving the problem ?
I believe that the problem is that when you do:
print(myFirstWhereFunc(intLst, 4, -1));
there are two possible ways to infer the type of myFirstWhereFunc:
Bottom-up (inside-out): myFirstWhereFunc is called with a List<int> and with int arguments, so its type could be myFirstWhereFunc<int>. This is what you want.
Top-down (outside-in): print has an Object? parameter, so myFirstWhereFunc could be myFirstWhereFunc<Object?> so that it returns an Object?. This is what actually happens and is what you do not want.
Dart ends up with two possible ways to infer the generic type parameter, both seem equally valid at compilation-time, and it picks the one that you happen to not want. Picking the other approach likely would result in undesirable outcomes for different code examples. Arguably inference could try both ways and pick the narrower type if one approach leads to a subtype of the other. I'm not sure offhand if that would break code, but I wouldn't be surprised. (I also suspect that it's been suggested in https://github.com/dart-lang/language/issues somewhere...)
Changing myFirstWhereFunc's return type to dynamic is a crude workaround to the problem because it makes myFirsyWhereFunc's type no longer inferrable from print's parameter type.
If you split the line up and use a temporary variable, inference can infer myFirstWhereFunc independently of print and then should do what you want:
var intResult = myFirstWhereFunc(intLst, 4, -1);
print(intResult);

Can you pass an extension method as a function argument in Dart?

Is there a way to pass an extension method as a function argument?
I'd like to pass an extension method to a .map method like a static function if it's possible.
Something like this:
extension Add10 on int {
int add10() {
return this + 10;
}
}
int add100(int x) => x + 100;
// I'd like to do something like this
[1, 2, 3, 3, 5].map(Add10.add10);
// Like I could do with a regular function
[1, 2, 3, 4, 5].map(add100);
// instead of
[1, 2, 3, 4, 5].map(x => x.add10());
Is this possible?
In other words, can an extension method on int that returns an int satisfy the signature
int Function(int)
like my add100 function can?
Or are extension methods always treated more like a class that must wrap the value before making the call?
No, not like that.
An extension method is like an instance method in this regard. You can't extract an instance method from int int to a function, pass it somewhere else, and then call that method on other integers.
Just like an instance method, you need to do:
[1, 2, 3, 3, 5].map((x) => x.add10())
That's one situation where extension methods are less usable than the static helper function they're intended to replace. As #eugene-kuzmenko points out, you can make the extension method a static function instead (not necessarily inside an extension declaration), and then you can tear it off an pass it as an argument, because then it's not inherently tied to a single receiver, but it takes the number to act on as an argument, like Iterable.map expects.
If you are going to turn the result of the map into a List anyway, I'd probably just use a literal:
var numbers = [1, 2, 3, 3, 4];
var newNumbers = [for (var x in numbers) x.add10()];
It looks slightly more cumbersome, but in practice I find it much more convenient to not have to write functions literals (and it also works with asynchronous operations then).
Technically you can use a static function inside extension
[1, 2, 3, 3, 5].map(**Add10.add10**);
So you can change your extension method(and function signature)
extension Add10 on int {
static int add10(int i) {
return i + 10;
}
}
But I don't think it's a good idea

How to use **kwarg in Dart (like in Python)

I have a question on how to easily use map as a parameter in Dart. Is there any easy way of passing all the key-values pairs of a map object to a function?
For example, I have a map and a function like this:
const testMap = {"a": 1, "b":2};
int testFunc(a, b){
return a + b;
}
and I want to use them like this:
testFunct(**testMap) // not possible in dart (though possible in python)
which should give us 3 as the result.
Any smart solution like this? Thanks!
Please note that ** is the python-way of passing the parameters inside dictionary: docs
It's not directly possible the way you write it, but you can do something similar using Function.apply.
You have to either pass the arguments as positional, and then you need to know the order:
const testMap = {"a": 1, "b":2};
int testFunc(a, b){
return a + b;
}
void main() {
print(Function.apply(testFunc, testMap.values.toList()));
}
or you have to use named parameters and then the map keys should be symbols:
const testMap = {#a: 1, #b:2};
int testFunc({required int a, required int b}){
return a + b;
}
void main() {
print(Function.apply(testFunc, [], testMap));
}
Dart distinguishes positional and named parameters, so if you want to refer to a parameter by name, it should be named.
The former approach is dangerous because you don't use the names of the map. It should really just be const testArguments = [1, 2]; and not include a map which doesn't help you.
Using Function.apply is not type safe. It's as type-safe as calling something with type dynamic or Function — which means not safe at all — so use it carefully and only when necessary.

Constant with all items of an enum in Delphi

Is it possible to have a constant set of all items of an enumerated type in Delphi?
type
TItems = (
iOne,
iTwo,
iThree
);
TItemsSet = set of TItems;
const
SOMEITEMS: TItemsSet = [iTwo, iThree];
ALLITEMS: TItemsSet = ?????
I would like ALLITEMS to always hold all members of TItems. And I would prefer to have this as constant.
Edited:
And what, if my enum looks like this:
TItems = (
iOne = 1,
iTwo = 2,
iThree = 5
);
(From the comments)
[Low(T)..High(T)] works for any type T that is small enough to be used as a set, to include all items that can be included in the set.
As noted in the comments, this is enough for the enumeration in the question, but in general, may include constants that aren't defined as part of the enumeration.

What is the difference between == and === in Dart?

Does Dart support == and === ? What is the difference between equality and identity?
Dart supports == for equality and identical(a, b) for identity. Dart no longer supports the === syntax.
Use == for equality when you want to check if two objects are "equal". You can implement the == method in your class to define what equality means. For example:
class Person {
String ssn;
String name;
Person(this.ssn, this.name);
// Define that two persons are equal if their SSNs are equal
bool operator ==(other) {
return (other is Person && other.ssn == ssn);
}
}
main() {
var bob = Person('111', 'Bob');
var robert = Person('111', 'Robert');
print(bob == robert); // true
print(identical(bob, robert)); // false, because these are two different instances
}
Note that the semantics of a == b are:
If either a or b are null, return identical(a, b)
Otherwise, return a.==(b)
Use identical(a, b) to check if two variables reference the same instance. The identical function is a top-level function found in dart:core.
It should be noted that the use of the identical function in dart has some caveats as mentioned by this github issue comment:
The specification has been updated to treat identical between doubles
like this:
The identical() function is the predefined dart function that returns
true iff its two arguments are either:
The same object.
Of type int and have the same numeric value.
Of type double, are not NaNs, and have the same numeric value.
What this entails is that even though everything in dart is an object, and f and g are different objects, the following prints true.
int f = 99;
int g = 99;
print(identical(f, g));
because ints are identical by their value, not reference.
So to answer your question, == is used to identify if two objects have the same value, but the identical is used to test for referential equality except in the case of double and int as identified by the excerpt above.
See: equality-and-relational-operators
As DART is said to be related to javascript, where the === exists, I wish not be downvoted very quickly.
Identity as a concept means that 1 equals 1, but 1.0 doesn't equal 1, nor does false equal 0, nor does "2" equal 2, even though each one evaluates to each other and 1==1.0 returns true.
It should be noted that in Dart, identical works similarly to Javascript, where (5.0 == 5) is true, but identical(5.0, 5) is false.

Resources