I am new to flultter and dart. I see main calls the first widget as follows with added print statements.
void main() {
print('begin ');
runApp(MyApp());
print('end');
}
I see another way is
void main() => runApp(MyApp());
but when I try following it does not work
void main() => { print(' begin '); runApp(MyApp()); };
My question is if I want to run multiple statements in second( => ) approach, how I can do that and what is the name of => operator ?
i dont know why no one answered but yes its possible to call many statements with an arrow function but you need a comma in between (simlair to passing arguments to function)
this can be usefull when passing many function to onTap or OnClick function
your exemple:
void main() => { print(' begin '), runApp(MyApp()) ,print(' end ')};
The => is not an operator, per se. It is a syntax that allows you to write one-liner functions that perform a single action and can also return a value. For example:
// Return a value
String getString() => 'a string';
// Do something
void doSomething() => doSomethingElse();
// It also works for getters
int _privateValue;
int get publicValue => _privateValue;
// They are also common in higher order functions
var numbers = [1, 2, 3, 4, 5];
var oddNumbers = numbers.where((n) => n % 2 != 0); // Output: [1, 3, 5]
Each of these examples is equivalent to a fully written-out method with curly brackets and return statements.
However, one-liner functions are, by definition, required to only have a single line of code. If you want a second line, you can't use a one-liner function and instead have to write a complete method:
// Incorrect, will cause the second statement to execute separately
// or will throw an error, depending on where and how you do this
void oneLinerFunction() => print('1'); print('2');
// The correct way to define a method with more than one line of code in it
void fullMethod() {
print('1');
print('2');
}
As far as your final example, combining => and {} doesn't make the one-liner function execute multiple lines. It makes the function attempt to return a map or a set, since that's what values within curly brackets means. For example:
Map<String, int> getMap() => { 'a': 1, 'b': 2 };
This will not work if you try to use it to sneak in multiple lines of code to the function. The compiler will interpret it as a set and will not work as you expect at best and throw an error at worst.
The => operator is referred to as the Arrow Operator
Functions defined inline with the => operator are referred to as Lambda Functions or Arrow Functions. These functions execute and return a single statement.
If you want to perform multiple statements, you can use Anonymous Functions. Specified with {} and without the => operator:
someFunc( () { print("1"); print("2"); print("3");} )
(Anonymous functions can have return values as well)
There's a big thread about it here on Stack Overflow
As others have said, => operator is referred to as the Arrow Operator and it is meant to be a one liner.
I came here wanting to have multiple lines of code in the onPressed of a button and this is one way to do it:
ElevatedButton(
onPressed: () {
print('one');
print('two');
},
child: Text("Click me"),
),
If you have a method that only contains one line, you can use => to save room and make the entire method declaration and body fit on one line. You can have multiple operations, as long as they fit on that single line. It basically translates to 'just return this value' (and it acts like a return statement).
void main() => runApp(MyApp());
is completely equivalent to saying:
void main(){
return runApp(MyApp());
}
However, if you have a method that includes multiple lines, you need to use brackets.
Related
I am writing a native plugin that, in some cases, has to call functions in the Flutter portion of the app, written in Dart.
How it's achieved, is explained here:
https://flutter.io/platform-channels/
Furthermore, an example of invoking a method from the native/platform part towards the Dart/non-native is here:
https://github.com/flutter/plugins/tree/master/packages/quick_actions
Now, this example is really nice in case the platform only needs to invoke a method, i.e. that call returns nothing/void, but in case it needs to invoke a function, i.e. needs a return value from the non-native/Dart part, I could not have found an example or documentation on the internet. I believe it can be implemented though, because in the native Java part, there is a method:
public void invokeMethod(String method, Object arguments, MethodChannel.Result callback)
So, there is a callback object that could have a return value from the non-native part - or, I am mistaken here, and there is currently no way of returning a value from the non-native Dart portion of the app?
The signature is void setMethodCallHandler(Future<dynamic> handler(MethodCall call)), so we need to provide a function at the Dart end that returns Future<dynamic>, for example _channel.setMethodCallHandler(myUtilsHandler);
Then implement the handler. This one handles two methods foo and bar returning respectively String and double.
Future<dynamic> myUtilsHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case 'foo':
return 'some string';
case 'bar':
return 123.0;
default:
throw MissingPluginException('notImplemented');
}
}
At the Java end the return value is passed to the success method of the Result callback.
channel.invokeMethod("foo", arguments, new Result() {
#Override
public void success(Object o) {
// this will be called with o = "some string"
}
#Override
public void error(String s, String s1, Object o) {}
#Override
public void notImplemented() {}
});
In Swift, the return value is an Any? passed to the result closure. (Not implemented is signaled by the any parameter being the const NSObject value FlutterMethodNotImplemented.)
channel.invokeMethod("foo", arguments: args, result: {(r:Any?) -> () in
// this will be called with r = "some string" (or FlutterMethodNotImplemented)
})
I can assign an arrow function, which returns a value to a function variable that requires a void signature. But I can not assign a block function that returns a value. Why? Should the not be arrow function restricted as well, as it returns a value?
arrow function
block function
That is because by doing
void Function(int) function=(a)=>b=a;
Dart assumes that you don't want to return the value of the assignation, that normally you could use, for example:
void main() {
int a=10,b;
print(b=a);
}
So, dart just thinks that you want to assign the variable, nothing more. Another more detailed example here:
int number=10;
late int target;
void main() {
print(test());
number+=10;
test2();
print(target);
}
int test()=>target=number;
void test2()=>target=number;
//Note: there aren't many best practices here (For example, global variables)
//Is just an example to make you understand, nothing more
but if you specify the return, dart will think you reeeeally want to return that value, and that's not possible, as it is a void function.
I'm using a lambda expression in my C# script in my Unity project to call a function with a parameter when a DOTween callback is called.
It simply looks like this: animation.OnComplete(() => DestroyOnCompleted(children));
It works just fine, but I am note sure why a lambda expression is used in this case. I know it has something to do with delegates, but other than that, I'm not too sure; and I would like to explain it to my exam, if I get asked about it.
Could anyone enlighten me? :-)
Why not? ;)
I don't know that API too much but it seems like it is simply expecting something like
OnComplete(TweenCallback callback)
where TweenCallback from your usage basically seems to equal the c# built-in Action delegate and basically simply a parameter less void
public delegate void TweenCallback();
so whether you pass in this callback as a lambda like
animation.OnComplete(() => DestroyOnCompleted(children));
or anonymous method using the delegate operator like
animation.OnComplete(delegate { DestroyOnCompleted(children); });
or using a method
animation.OnComplete(OnCompletedAnimation);
...
private void OnCompletedAnimation()
{
DestroyOnCompleted(children);
}
is basically equivalent.
The main difference between the first two and the last one is: Where does children come from?
The lambda and delegate way allows you to pass in children from the current scope variables without having to store it in any field!
If you look at the documentation of DotTween, you see that row:
Now looking at the Source Code of DotTween, you can see the definition of TweenCallback:
public delegate void TweenCallback();
So the question now is, what is a delegate void in c#?
A delegate in c# is basically an object that "represent" a function.
But functions are not all the same, they can have parameters in input and return something (or return void).
To understand what kind of function does a delegate represent, try to just remove the keyword delegate.
For example, the TweenCallback without the keyboard delegate is:
public void TweenCaalback()
So the delegate represent a void function that has no parameters in input! (And it is Public).
What does it means represent a function?
It means that this is valid code:
void DoNothing()
{
}
TweenCallback x = DoNothing;
x();
So you can "assign functions" to a delegate that has the same function signature.
In this case, TweenCallback is a delegate void (), so you can assign to it a void() function.
What is a lambda?
A lambda is an expression of that style:
(string name, int age) => { return 3 };
you can read that as "string name and int age go in return 3"
That's a more concise way to describe that function:
int AnonymousFunction (string name, int age) {}
The main difference is that lambdas do not have any name. If you have not any parameter in input the lambda become like this:
() => {return 3;}
If you have only one statement inside the {} you are allowed to write it more shortly as
() => 3;
Final step
Is this valid code?
void DoNothing()
{
}
TweenCallback x = () => DoNothing();
Yes it is! Tween callback is expects a void () function.
() => DoNothing(); Is a lambda (un-named function) that takes nothing in input and calls some other function. It's the shorter version of () => {DoNothing();} that you have to think as void () {DoNothing();}
So when writing
animation.OnComplete(() => DestroyOnCompleted(children));
You are just passing a void () function to OnComplete Method, that makes sense because TweenCallback is a void () delegate.
Notes
As you can see, functions and lambdas expression can be converted implicitly to delegates. But you have to understand that they are all different things, and in more advanced coding scenarios that distinction is not just pure theory.
What is the difference between main() and void main() in Flutter
The only answers that I could find on the internet are about C++ or sth like that.
Well, let's see:
void main() {
print(main.runtimeType);
}
will print () => void. That means a function with no parameters returning void.
While
main() {
print(main.runtimeType);
}
will print () => dynamic. That means a function with no parameters returning dynamic.
The valid return type for the main function is void:
Every app must have a top-level main() function, which serves as the entrypoint to the app. The main() function returns void and has an optional List<String> parameter for arguments.
Source
So strictly speaking, having no return type (that means defaulting to the type dynamic) is wrong. But that is the simplified beginners instructions, so there are exceptions. But when in doubt, do it by the book.
the different is when return a value from the function in void read() you can't return any type of value ..
While in read()you can return any type of value weather is int , double , String , list and also a set Because it's dynamic also you can type dynamic read() it's same as read()
void main () {
// print(iifo.runtimeType);
var k = iifo() ;
print(k) ;
}
iifo ( ) {
return ('Stack') ;
}
output
Stack
in return line you can return any type of data (int , double , String , bool , list, etc....).
This answer does not address your question directly, since I see that it has been already answered properly. However, you might find good to know that the main function in a Dart application can also return Future<void> instead of void, since you can tag the main function as an async function.
In the particular case of a Flutter application, this means that you can do whatever you need to do before running runApp(...) in the main() method body, even asynchronously. This way, the splash screen will be shown until your asynchronous result is retrieved, before calling runApp(...). For example, setting a landing widget depending on the result of an asynchronous task:
Future<void> main() async {
// Do whatever you need to do here
final home = await createHomeWidgetDependingOnAsyncResult();
return runApp(MyApp(home: home));
}
I found it the problem, I wrote:
import 'LanguagesScreen.dart';
Instead of:
import 'package:flutter_projects/LanguagesScreen.dart';
As a complete beginner learning Dart, I want to understand if the void type is required for a main function. In the official language tour: https://dart.dev/guides/language/language-tour#a-basic-dart-program the examples do not include the void keyword/type.
But in other places we seed void main() { ...
The following two snippets of code have the same output:
main() {
print('Hello World!');
}
Runs fine on Dart Pad: https://dartpad.dartlang.org/fa6f6e5a7b9406e88b31a17e82655ef8
(we don't see any compiler warnings or advice suggesting the void should be added)
void main() {
print('Hello World!');
}
Is the void a convention that nobody questions or can we exclude it without any consequences?
Note: I'm aware of the history of void keyword/type, I just want to understand if I can safely omit the void from more advanced programs or if it's required.
https://en.wikipedia.org/wiki/Void_type
https://medium.com/flutter-community/the-curious-case-of-void-in-dart-f0535705e529
https://medium.com/dartlang/dart-2-legacy-of-the-void-e7afb5f44df0
The Dart 2.2 language specification says:
18.4 Scripts
A script is a library whose exported namespace (18.2) includes a top-level
function declaration named main that has either zero, one or two required arguments.
The spec imposes requirements on the name and the arity (and types) of its arguments. There is no requirement on its return type, so using a different type (such as dynamic, which is what it would be if you omit void) would have no effect.
Declaring no type is identical to declaring void.
I'm not sure if Flutter/Dart want the void there for some sort of "identification" but I doubt it. If it runs, it should be 100% the same.
The Dart linter has the following rule:
always_declare_return_types (ref)
DO declare method return types.
When declaring a method or function always specify a return type. Declaring return types for functions helps improve your codebase by allowing the analyzer to more adequately check your code for errors that could occur during runtime.
BAD:
main() { }
_bar() => _Foo();
class _Foo {
_foo() => 42;
}
GOOD:
void main() { }
_Foo _bar() => _Foo();
class _Foo {
int _foo() => 42;
}