Import extension method from another file in Dart - flutter

With Dart 2.6, I can use extension methods like this :
extension on int {
int giveMeFive() {
return 5;
}
}
main(List<String> arguments) async {
int x;
x.giveMeFive();
}
Everything works perfectly ! :D
But now if I want to put my extension method in another file like this :
main.dart
import 'package:untitled5/Classes/ExtendInt.dart';
main(List<String> arguments) async {
int x;
x.giveMeFive();
}
ExtendInt.dart
extension on int {
int giveMeFive() {return 5;}
}
It fails with a depressing error ..
bin/main.dart:9:5: Error: The method 'giveMeFive' isn't defined for the class 'int'.
Try correcting the name to the name of an existing method, or defining a method named 'giveMeFive'.
x.giveMeFive();
^^^^^^^^^^
Is it not allowed to do that or am I doing something wrong ?
Thanks for reading ! :)

This is working as intended. An extension with no name is implicitly given a fresh name, but it is private. So if you want to use an extension outside the library where it is declared you need to give it a name.
This is also helpful for users, because they may need to use its name in order to be able to resolve conflicts and explicitly ask for the extension method giveMeFive from your extension when there are multiple extensions offering a giveMeFive on the given receiver type.
So you need to do something like
extension MyExtension on int {
int giveMeFive() => 5;
}

Related

Flutter : A member named 'read' is defined in extensions 'ReadContext' and 'BuildContextX' and neither is more spesific

I have a button in my application that return :
onPressed: () {
return context
.read(FavoriteIds.provider.notifier)
.toggle(doa.id.toString());
},
In this case, i used a riverpod provider. But when i want to import a flutter_bloc package, the read keyword will be error with this message
A member named 'read' is defined in extensions 'ReadContext' and 'BuildContextX' and neither is more specific. Try using an extension override to specify the extension you want to to be chosen.
Please help me solve this problem. thank you :)
Here the problem is read() is defined in both ReadContext & BuildContextX extensions. So the compiler is not getting which extension to use.
To solve the error, use : ReadContext(context).read if you wanna access bloc or BuildContextX(context).read() as per your need.
This means you are importing 2 extensions that both supply the same method read. Consider this example:
extension Ext1 on String {
void foo() => print("from extension 1");
}
extension Ext2 on String {
void foo() => print("from extension 2");
}
void main() {
String s = "hello";
s.foo();
}
What should this code print? There isn't an obvious answer, and to avoid accidental programming errors, Dart prohibits this.
You could try "go-to definition" (ctrl/cmd click in most IDEs) on the read method to navigate to one of the files that it is defined in, and then delete the corresponding import statement.
However, it might be quicker to just delete all the import statements in that file and add them back with autocomplete

What does mean of using the "this" keyword in Dart?

I'm sorry if this sounds like an extremely foolish question but it's really been bugging me.
What is the "this." that I see? Whenever I see the documentation in flutter I see it used in things like the following in the documentation:
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers
I'll be more than happy to also read up any links or documentation regarding it.
The 'this' keyword refers to the current instance.
You only need to use this when there is a name conflict. Otherwise, Dart style omits the this.
class Car {
String engine;
void newEngine({String engine}) {
if (engine!= null) {
this.engine= engine;
}
}
}
So you can be consistent with the name of your parameters, either in the constructor or in some function in the class.
class Car {
String engine;
void updateEngine({String someWeirdName}) {
engine = someWeirdName;
}
}
If you don't have a name conflict, you don't need to use this.
In other languages ​​like Python and Swift, the word 'self' will do the same thing as 'this'.
Basically, this keyword is used to denotes the current instance. Check out the below example.
void main() {
Person mike = Person(21);
print(mike.height);
}
class Person {
double height;
Person(double height) {
height = height;
}
}
When we run this dart code, it outputs null as the height. Because we have used height = height inside the Person constructor, but the code doesn't know which height is the class property.
Therefore, we can use this keyword to denotes the current instance and it will help the code to understand which height belongs to the class. So, we can use it as below and we will get the correct output.
void main() {
Person mike = Person(21);
print(mike.height);
}
class Person {
double height;
Person(double height) {
this.height = height;
}
}
Use of this keyword
The this keyword is used to point the current class object.
It can be used to refer to the present class variables.
We can instantiate or invoke the current class constructor using this keyword.
We can pass this keyword as a parameter in the constructor call.
We can pass this keyword as a parameter in the method call.
It removes the ambiguity or naming conflict in the constructor or method of our instance/object.
It can be used to return the current class instance.

Unable to use generic function in a generic function

I have the following class in my code
abstract class DatabaseKey<T> implements Built<DatabaseKey<T>, DatabaseKeyBuilder<T>> {
DatabaseKey._();
factory DatabaseKey([void Function(DatabaseKeyBuilder<T>) updates]) = _$DatabaseKey<T>;
String get name;
}
Then, I define the following generic typedef function:
typedef ObserveDatabaseEntity = Observable<DatabaseEntity<T>> Function<T>(DatabaseKey<T> key);
But, when I try to use it as follows, the code has an error.
static ObserveConfigurationValue observe(
GetConfigurationState getState,
ObserveDatabaseEntity observeDatabaseEntity,
) {
assert(getState != null);
assert(observeDatabaseEntity != null);
return <KT>(ConfigKey<KT> key) {
return Observable.just(getState())
.flatMap((state) {
final dbKey = _databaseKeyFromConfig<KT>(key);
return observeDatabaseEntity(dbKey)
.map(_configValueFromDatabaseEntity);
});
}
}
DatabaseKey<T> _databaseKeyFromConfig<T>(ConfigKey<T> key) {
return DatabaseKey((build) => build
..name = key.value,
);
}
The error I am getting is:
The argument type DatabaseKey can't be assigned to the parameter DatabaseKey.
I see nothing wrong with this code or why it shouldn't work, but maybe my understanding of what can be written in Dart is wrong. What would be the correct way to write this, if possible at all?
EDIT#1:
Note:
The typedef ObserveDatabaseEntity is in one file
The static ObserveConfigurationValue observe(GetConfigurationState getState, ObserveDatabaseEntity observeDatabaseEntity) is is another file
From playing around, it seems that placing them in a single file, the error disappears.
Still, I believe that this should work in separate files as well,
This error looks like an import mismatch.
In dart, you can import file either through relative path or package.
import 'lib/some_file.dart'; //relative
import 'package:myapp/lib/some_file.dart'; //package
There's really no better way but once you choose one, you have to stick to it. If you don't (meaning you have imported a file using a package import and the same file elsewhere with a relative path) Dart will place them in two different namespaces and think they are two different classes.

Class in parameter of function (Arduino) does not compile

I am trying to create a simple class in C++, but I keep getting the compilation errors:
main:2: error: variable or field 'doSomething' declared void
main:2: error: 'person' was not declared in this scope
main:
class person {
public:
int a;
};
void doSomething(person joe) {
return;
}
main() and stuff would go here, but even if I include main(){}, the errors still occur. I also tried adding 2 closed parentheses after joe, but then that creates the error:
main: In function 'void doSomething(person (*)())':
main:8: error: request for member 'a' in 'joe', which is of non-class type 'person (*)()'
Any help is greatly appreciated. (I hope this isn't something really stupid I'm missing, because I've been researching for hours).
Edit: I found out this is an Arduino-specific error. This post answers it.
I found out after reading this post that a way to work around this is:
typedef struct person{
public:
int a;
};
void doSomething(void *ptr)
{
person *x;
joe = (person *)ptr;
joe->a = 3; //To set a to 3
//Everything else is normal, except changing any value of person uses "->" rather than "."
return;
}
main()
{
person larry;
doSomething(&larry);
}
So essentially it is:
-Change class to typedef struct
-in the parameter, replace newtype with void *something
-add person *x; and x = (person *)ptr; to the beginning of the function
-whenever accessing type property, use -> rather than .
I'm not a expert but when I try to do what you want to do, I do it this way:
//create an instance of my class
MyAwesomeClass myObject;
void myFunction(MyAwesomeClass& object){
//do what you want here using "object"
object.doSomething();
object.doSomethingElse();
}
void setup() {
//setup stuff here
myObject.init();
}
void loop() {
//call myFunction this way
myFunction(myObject);
}
As I said, I'm not a C++ expert but it does the job.
Hope it helps!
My guess is, you have an invalid syntax error somewhere in the declarations above "class person...". Can you copy and paste the whole file?

Get type of class field with null value in Haxe

Is it possible to get class of field with null value in haxe?
The function "Type.getClass" gets class of value (setted at runtime), but I need to get class defined in a compilation-time.
Function "getClassFields" returns only names of fields, without classes.
For example:
class MyCls
{
public static var i:Int = null;
public static var s:String = null;
}
trace(Type.getClass(MyCls.i)); // show "null", but I need to get Int
trace(Type.getClass(MyCls.s)); // show "null", but I need to get String
And in my situation I can't to change sources of class MyCls.
Thanks.
You can try Runtime Type Information. It's a Haxe feature which allow go get full description of a type in runtime.
http://haxe.org/manual/cr-rtti.html
Since you need to get the types for null fields, you really need to resort to Haxe's Runtime Type Information (RTTI) (as #ReallylUniqueName recomended).
import haxe.rtti.Rtti;
import haxe.rtti.CType;
class Test {
static function main()
{
if (!Rtti.hasRtti(MyCls))
throw "Please add #:rtti to class";
var rtti = Rtti.getRtti(MyCls);
for (sf in rtti.statics)
trace(sf.name, sf.type, CTypeTools.toString(sf.type));
}
}
Now, obviously, there's a catch...
RTTI requires a #:rtti metadata, but you said you cannot change the MyCls class to add it. The solution then is do add it through a macro in your build file. For instance, if you're using a .hxml file, it should then look like:
--interp
--macro addMetadata("#:rtti", "MyCls")
-main Test
With this and your own MyCls definition, the output would look like:
Test.hx:11: i,CAbstract(Int,{ length => 0 }),Int
Test.hx:11: s,CClass(String,{ length => 0 }),String