Is there any way to convert an int to a int Function() in Dart?
For example:
a to ()=>a
You mean like this? This function will return a function which returns the int value you provided when the method was created.
int Function() intToIntFunction(int i) => () => i;
Updated
You can also do this if you want the current value of the integer each time the method are called:
void main() {
int a = 5;
int Function() funA = () => a;
print(funA()); // 5
a++;
print(funA()); // 6
}
Related
I see this source from google_fonts of dart pub. It seems we have a function map? and asMap() has a arrow function? Don't understand this.
static Map<
String,
TextStyle Function({
TextStyle? textStyle,
Color? color,
Color? backgroundColor,
double? fontSize,
FontWeight? fontWeight,
FontStyle? fontStyle,
double? letterSpacing,
double? wordSpacing,
TextBaseline? textBaseline,
double? height,
Locale? locale,
Paint? foreground,
Paint? background,
List<ui.Shadow>? shadows,
List<ui.FontFeature>? fontFeatures,
TextDecoration? decoration,
Color? decorationColor,
TextDecorationStyle? decorationStyle,
double? decorationThickness,
})> asMap() => const {
'ABeeZee': GoogleFonts.aBeeZee,
'Abel': GoogleFonts.abel}
You're seeing a generated code, in the very beginning of the file:
// GENERATED CODE - DO NOT EDIT
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
This function is defined as:
Name: asMap.
Scope: top-level (Since it is a static method).
Return type: Map<String, TextStyle Function({ ...args })>.
It seems we have a function map?
We have a function that returns a map of Strings and Closures. In Dart this is perfectly fine:
final Map<String, int Function(int, int)> operations = {
'sum': (int a, int b) => a + b,
'subtract': (int a, int b) => a - b,
'multiply': (int a, int b) => a * b,
'divide': (int a, int b) => a * b
};
operations['sum']!(30, 30); // 60
operations['subtract']!(30, 30); // 0
operations['multiply']!(30, 30); // 900
operations['divide']!(30, 30); // 1
In general this is not something we do by raw hands due to type implications (hard to maintain, you can see that it's pretty confusing + it's pretty easy to lost track of type definitions and, consequently, all intellisense features). So that's why this is being done through code generation.
And in this particular case, we are generating a map, like this example below:
class Arithmetic {
static int sum(int a, int b) {
return a + b;
}
static int subtract(int a, int b) {
return a - b;
}
static int multiply(int a, int b) {
return a * b;
}
static int divide(int a, int b) {
return a * b;
}
static Map<String, int Function(int, int)> asMap() {
const Map<String, int Function(int, int)> operationsAsMap = {
'sum': sum,
'subtract': subtract,
'multiply': multiply,
'divide': divide
};
return operationsAsMap;
}
}
asMap() has a arrow function?
No, the asMap() implementation is using an arrow function, which is an alias for:
// This is a shorthand...
static Map<...> asMap() => const { ... };
// For this:
static Map<...> asMap() {
return const { ... };
}
This snippet is of no practical significance. I've been just getting used to the closure idea.
var cls = () {
var x = 5;
return {
'x': x,
'inc': () {x++;},
};
} ();
void main() {
print(cls['x']);
print(cls['inc']);
cls['inc']();
print(cls['x']);
}
DartPad output:
5
Closure '_closure'
5
Error compiling to JavaScript:
main.dart:18:13:
Error: The method 'call' isn't defined for the class 'dart.core::Object'.
The desired output would have been something like
5
6
What'd be the cleanest approach to this kind of exercise?
UPD:
The working example, courtesy of Günter Zöchbauer:
var cls = () {
var x = 5;
var map = <String, dynamic>{
'x': x,
};
map['inc'] = () {map['x']++;};
return map;
} ();
void main() {
print(cls['x']);
print(cls['inc']);
cls['inc']();
print(cls['x']);
}
DartPad output:
5
Closure '_closure'
6
You have to declare the 'x' entry as a Function.
In your code, you set 'x' to the value of the 'x' variable (5) when you return the map. The value will always be 5 and will not update.
var cls = () {
var x = 5;
return {
'x': () => x,
'inc': () {x++;},
};
}();
void main() {
print(cls['x']()); // 5
print(cls['x']); // Closure: () => int
print(cls['inc']); // Closure: () => Null
cls['inc']();
print(cls['x']()); // 6
}
var x = 5;
var cls = () {
return {
'x': x,
'inc': () {x++;},
};
} ();
You would need to move out the variable declaration, otherwise you'd re-declare and re-initialize it to 5 at every call.
update
var cls = () {
var x = 5;
var map = {
'x': x,
// 'inc': () {map['val']++;}, // not possible to reference the `map` variable that is just declared here so we need to move this out
};
map['inc'] = () {map['x']++;};
} ();
Simplified code example:
int value() => 1;
main() {
int value = value(); // Error here: 'value' isn't a function
}
Is there a way to specify that I want to call a function?
If no, why is it impossible?
You can use an import prefix
import 'this_file.dart' as foo;
int value() => 1;
main() {
int value = foo.value(); // Error here: 'value' isn't a function
}
I know you can specify function types in formal arg list, but how would I do this for instance variables? I would like to do this:
class A<T> {
int compare(T a, T b);
}
where compare is a function variable with the appropriate type. I would like to be able to write:
A a = new A();
a.compare = ...
You can use typedef :
typedef Comparison<T> = int Function(T a, T b);
class A<T> {
Comparison<T> compare;
}
main() {
A a = new A<int>();
a.compare = (int a, int b) => a.compareTo(b);
print(a.compare(1, 2));
}
In addition to the Alexandre Ardhuin's answer, direct declaration, without typedef:
class A<T> {
late int Function(T a, T b) compare;
}
main() {
A<int> a = new A<int>();
a.compare = (int a, int b) => a.compareTo(b);
print(a.compare(1, 2));
}
Does Dart support the concept of variable functions/methods? So to call a method by its name stored in a variable.
For example in PHP this can be done not only for methods:
// With functions...
function foo()
{
echo 'Running foo...';
}
$function = 'foo';
$function();
// With classes...
public static function factory($view)
{
$class = 'View_' . ucfirst($view);
return new $class();
}
I did not found it in the language tour or API. Are others ways to do something like this?
To store the name of a function in variable and call it later you will have to wait until reflection arrives in Dart (or get creative with noSuchMethod). You can however store functions directly in variables like in JavaScript
main() {
var f = (String s) => print(s);
f("hello world");
}
and even inline them, which come in handy if you are doing recusion:
main() {
g(int i) {
if(i > 0) {
print("$i is larger than zero");
g(i-1);
} else {
print("zero or negative");
}
}
g(10);
}
The functions stored can then be passed around to other functions
main() {
var function;
function = (String s) => print(s);
doWork(function);
}
doWork(f(String s)) {
f("hello world");
}
I may not be the best explainer but you may consider this example to have a wider scope of the assigning functions to a variable and also using a closure function as a parameter of a function.
void main() {
// a closure function assigned to a variable.
var fun = (int) => (int * 2);
// a variable which is assigned with the function which is written below
var newFuncResult = newFunc(9, fun);
print(x); // Output: 27
}
//Below is a function with two parameter (1st one as int) (2nd as a closure function)
int newFunc(int a, fun) {
int x = a;
int y = fun(x);
return x + y;
}