Where is num's operator == defined in Dart? - dart

When I run this code in my Android emulator, it prints the following.
void main() {
print(1 == 1.0); // true
print(identical(1, 1.0)); // false
}
I also read that the default implementation of == is identical. That means the operator == is overridden, however, when I went to num class to see its implementation, it shows the method is abstract.
bool operator ==(Object other);
So, I went to see its implementation in double and int classes but couldn't find anything there. So, where is that magic happening?

These are implemented at the native level and the Dart declarations are just an interface for these implementations. These implementations can be found at sdk/sdk/lib/_internal/ in the Dart sdk repository.
If you want to see the implementation in the VM you can go down to the vm/lib folder and find the double and integer implementations, which include the operators.
I'll use the VM implementation of integers as an example which defines the == operator and a method it uses:
#pragma("vm:recognized", "asm-intrinsic")
#pragma("vm:exact-result-type", bool)
#pragma("vm:never-inline")
bool operator ==(Object other) {
if (other is num) {
return other._equalToInteger(this);
}
return false;
}
#pragma("vm:recognized", "asm-intrinsic")
#pragma("vm:exact-result-type", bool)
bool _equalToInteger(int other) native "Integer_equalToInteger";
You can find the same for doubles and possibly something similar for the dart2js compiler. It's possible, however, that the JS compiler doesn't need a special definition because the defined behavior of the == operator of num seems to be identical to that of JS.

Related

Dart "upcasting" is not actually upcasting

I am trying to up-cast the subclass object but it is not working.
The following program compiles without any errors.
VideoStreamModel model = VideoStreamModel("");
VideoStream entity = model;
print(model); // prints VideoStreamModel
print(entity); // prints VideoStreamModel
print(entity as VideoStream); // prints VideoStreamModel
print(cast<VideoStream>(model)); // prints VideoStreamModel
I have written a testcase to test the relation of above two classes and it passes.
test('should be a subtype of VideoStream', () async {
expect(model, isA<VideoStream>());
});
What could be the problem here?
EDIT:
[deleted]
EDIT 2:
[deleted]
Edit 3:
Here is the complete code reproducing the error.
import 'package:equatable/equatable.dart';
import 'package:test/test.dart';
class A extends Equatable {
final String x;
A(this.x);
#override
List<Object> get props => [x];
}
class B extends A {
B(String x) : super(x);
A method() {
B b = B(x); // doing A b = A(x) makes the test pass
return b;
}
}
void main() {
B b = B("");
test('test', () async {
final expected = A(b.x);
final actual = b.method();
expect(actual, expected);
});
}
It generates the following assertion error:
Expected: A:<A>
Actual: B:<B>
print is calling the toString() on the object you are pointing at (in this case VideoStreamModel) which knows what type it is. When you are casting, you are not changing anything about the object itself but only how the compiler should see the object when it determines if you are allowed to use a given typed variable to point to the object.
So when you are doing entity as VideoStream you are really just telling the compiler that you "promise" that the entity can be seen as a VideoStream. But on runtime, this cast will be tested to see if it is true.
All of this is really not an issue since you should never test for the specific type of the object when you are programming Dart but instead use the is operator which tests if a given object is compatible with a given interface.
So e,g, (entity is VideoStream) will return true.
Updated part
You problem seems to be a misunderstanding of the use of Equatable. It is important to notice that Equatable are not only using the elements from props to determine if two objects are equal but it also looks at the runtimeType. You can see this from the implementation:
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is Equatable &&
runtimeType == other.runtimeType &&
equals(props, other.props);
https://github.com/felangel/equatable/blob/master/lib/src/equatable.dart#L46
This means that:
A a = A("");
B b = B("");
print(a == b); // false
When you are using expect without any matcher, it will just make an == operation which is stated in the documentation:
matcher can be a value in which case it will be wrapped in an equals matcher
Since we (as stated before) cannot change the runtimeType of an object after its creation you need to implement your own == if you want the two object instances to be seen as equal since equatable does only see two objects as equal if they both is created from the same class and contains the same values defined with props.

mql4 } not all control paths return a value

I have taken this function from another mql4 script. The other script compiles absolutely fine with no error. Strangely, now that I have copied this function into my script I get the error } not all control paths return a value
I understand the concept of return a value but not sure when there is a compile difference between the scripts
int ModifyOrder(int ord_ticket,double op, double price,double tp, color mColor)
{
int CloseCnt, err;
CloseCnt=0;
while (CloseCnt < 3)
{
if (OrderModify(ord_ticket,op,price,tp,0,mColor))
{
CloseCnt = 3;
}
else
{
err=GetLastError();
Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
if (err>0) CloseCnt++;
}
}
}
Most likely the difference is in #property strict. if using strict mode, you have to redeclare local variables, return value from every function (except void, of course) and some other differences.
In your example the function has to be ended with return CloseCnt; or maybe something else.
No way to declare non-strict mode - simply do not declare the strict one.
Once you declared it, it is applied to that file, and included into other files if importing.

Multiple types for a single variable (parameter/return type)

I am very new to Dart so excuse me if I didnt see this part.
I want to make a union type e.g. for a function input. In TS this would be:
let variableInput: string | number
typedef doesnt really define types but functions and enums dont really help too.
On the other side how should it look like when a function return either one or the other of two types? There must be something I dont see here.
There are no union types in Dart.
The way to do this in Dart is returning/accepting dynamic as a type:
dynamic stringOrNumber() { ... }
void main() {
final value = stringOrNumber();
if (value is String) {
// Handle a string value.
} else if (value is num) {
// Handle a number.
} else {
throw ArgumentError.value(value);
}
}
See also: https://dart.dev/guides/language/sound-dart

Have single line empty constructors, but braces on newline everywhere else

I am looking for a way to make clang-format allow single line empty constructors, but to put braces on the newline everywhere else.
Ideally I want to support these three cases all with one clang config.
Test::Test(const std::string &name) : name(name) {}
std::string Test::get_name()
{
return name;
}
void Test::blank()
{
}
Is there a way to special case constructors in anyway? Even being able to have empty functions on a single line the same as constructors would be acceptable. But putting short functions on a single line is not acceptable.
This doesn't solve all the issues, but it solves my main case.
AllowShortFunctionsOnASingleLine: InlineOnly
This will allow short functions in class definitions to be single line.
From https://clang.llvm.org/docs/ClangFormatStyleOptions.html
SFS_InlineOnly (in configuration: InlineOnly) Only merge functions defined inside a class. Same as “inline”, except it does not implies “empty”: i.e. top level empty functions are not merged either.
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
This combined with BreakBeforeBraces: Allman gives me the desired result.

How to prevent function return result declaratively?

Assume such conditions:
Some operation does not provide possibility of returning the result.
This operation declared as callback
Using typedef not recommended
Some operation provide of returning the result.
This operation declared as callback
Using typedef not recommended
Assume such scenario:
void main() {
executeVoidOperation(methodNonVoid); // Must throw if method void?
executeNonVoidOperation(methodVoid); // Must throw if method non-void?
}
int methodNonVoid() {
return 0;
}
void methodVoid() {
}
void executeVoidOperation(void operation()) {
operation(); // Must throw if method non-void?
}
void executeNonVoidOperation(dynamic operation()) {
var result = operation(); // Must throw if method void?
print(result); // Result of void operation? (if such passed as argument)
}
Displayed results:
null
Questions (where I wrong?):
Null is object. From where this null appeared (as result) if void function cannot return result (even null)?
Functions with different return types in Dart assumed as the same (not conflicting) types?
How in Dart called this function transformations?
executeNonVoidOperation(methodVoid); works because the callback is defined as dynamic operation(). dynamic can be anything, including void. It's the same as if you just don't specify a type.
The null value stems from a simple rule in Dart. Quoted from the Dart Language Tour:
All functions return a value. If no return value is specified, the statement return null; is implicitly appended to the function body.
That means that every void method always returns null. If you try to return something else, you'll get a runtime error (in checked mode).
executeVoidOperation(methodNonVoid); is a bit more tricky - I'd expect it to throw a runtime error, but it seems the callback is treated as dynamic operation() instead of void operation(). Dart Editor's analyzer seems to think that, too. This may be either a bug or a design choice by the Dart team.

Resources