You may never have noticed me, but you must have heard of my brother Flutter and our father Google.

The origin of

Dart was born in 2011, but had a tepid run until 2017. Dart was originally used internally at Google to build web and mobile applications. Dart caught everyone’s attention by attaching itself to Flutter’s fury.

Common grammar

Dart is fairly straightforward for those of you who are familiar with TypeScript to get started with. Here are some common Dart syntax for developing Flutter.

var number = 1; /// Dart will infer that number is an int, and assign it another type, such as a string, A value of type 'String' can't be assigned to A variable of type 'int'.
int number = 1;

var number = 1.0; /// Dart will infer that number is a double;
double number = 1.0;

dynamic variable = 1; /// You can use dynamic to specify dynamic types, but it is strongly recommended not to code this way; you will lose your friends
variable = '2';

String string = 'string'; /// Declaration string
String string = "string"; /// You can also use double quotation marks

var empty; /// Dart does not have undefined, but only null, indicating that empty == null is true
var empty = null; /// That's the same thing as up here. I could but I don't have to write it that way

null= =null; /// Dart == is equivalent to JavaScript ===, dart does not have the non-strict comparison in JavaScript (==)

double pi = 3.14;
String combineStr = '${pi}PI prime.; /// String template
String combineStr = '$piPI prime.; /// You can even omit {}, note: '$pixxx is the value of PI ', which cannot be omitted because DART assumes the variable name is pixxx

f() {} /// Declare a function
void f() {} /// It is recommended to declare a function with a return type. If there is no return statement, the function returns NULL by default.
int f() => 1; /// And int f() {return 1; } equivalent

void f(int a, b, c) {} /// Mandatory positional parameter, preceded by type to indicate parameter type (recommended)
void f(a, b, [c]) {} /// C is optional. The optional parameter must come after the mandatory parameter
void f(a, b, [c = 1]) {} /// If c is not transmitted, it is 1
void f(a, { b, c = 1{}})/// The parameters wrapped in {} are named parameters, which are optional and can be used as f(1, b: 2, c: 3). Named parameters are similar to JSON objects in JavaScript, but more concise and elegant

List<int> arr = [];
arr.add(1); /// A new
arr.removeLast(); /// Delete the last item
arr.where((e) => e > 0).toList(); /// Methods such as where filter to return Interable objects and need toList back toList
arr.map((e) => e * 2).toList(); /// Use map to convert arrays
arr.firstWhere((e) => e > 0, orElse: () => null); /// This is a bit different from JavaScript. Dart does not find the required item, but by default throws a StateError, unless you provide an orElse method that returns null if it does not find the item

/// Dart iterates through arrays of numbers to get subscripts is a bit more cumbersome than JavaScript
List<String> arr = ['apple'.'orange'.'peach'];
arr.asMap().entries.forEach((e) {
  /// 0 apple
  /// 1 orange
  /// 2 peach
  print('${e.key} ${e.value}');
});

/// Map types are similar to objects commonly used in JavaScript
Map map = { 'apple': 'apple'.'orange': 'orange' }
/// Get the value of a key. Note that you cannot use the map.apple form
map['apple']

/// Boolean values. It is important to note that dart's if criteria must be Boolean values and will not be converted implicitly like JavaScript
true
false
Copy the code

Here are some of the syntax tips that Dart uses in your daily development.

Final and const

In JavaScript, we use const syntax for declaring constants, such as an array const arr = [1, 2, 3]. But does that really guarantee that the array is immutable? As we all know, no. After all, a constant in JavaScript simply means that the variable cannot be reassigned, but for the above code we can still change the contents of the array by performing arr.push(4), etc.

Dart does not have this problem, and attempts to modify a const variable will throw an error (constants declared in final will work just as in JavaScript) :

Unsupported operation: Cannot modify an unmodifiable list
Copy the code

In Dart, const is a compile-time constant whose value is determined at compile time, while final is a run-time constant whose value is determined at run time. In other words, const constants must be initialized at declaration time and are determinable values, not computed values, whereas final constants must be initialized at declaration time or ina constructor, and their value can be evaluated dynamically. Here’s an example:

const c1 = "hello"; /// Correct, compile-time constant final f1 = "hello"; /// Correct, runtime constant const c2 = datetime.now (); /// compile-time constant final f2 = datetime.now (); /// Correct, run-time constantsCopy the code

Interesting.. operator

Dart has a cascading operator.. It’s interesting, and it’s used in everyday development. Suppose we want to get an HTML element, set some properties, and add a method listener. Normally, we might want to instantiate Person and call the say method.

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed! '));
Copy the code

In Dart, we can use.. The operator is written like this:

querySelector('#confirm') /// Get the object
  ..text = 'Confirm' /// Set properties
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed! '));
Copy the code

The first method call querySelector() returns a selector object. The code following the cascading symbol runs on this selector object, ignoring any subsequent values that might be returned.

Unique closure

List<Function> funs = List(100);
for (var index = 0; index < 100; index++) {
  funs[index] = () => print(index);
}
funs.forEach((f) { f(); });
Copy the code

In JavaScript, the effect of this code is to print 99 100 times, with each closure capturing the value of the same variable index set in the last iteration, which is 99. This is logical, but not intuitive. In Dart, each iteration allocates a new variable, so the code above prints 0, 1… , 99.

Handy assert

In daily development, we write many methods, and there are some parameters that we may want to restrict, such as passing only integers greater than zero, and so on. In Dart we can display and declare our expectations by adding assertions as appropriate. For example, we have a factorial solution:

factorial(int x) {
  return x == 0 ? 1 : x * factorial(x - 1);
}
Copy the code

If the above code evaluates factorial(-1), the function will recurse indefinitely until the stack space is full. In Dart, we can say:

factorial(int x) {
  assert(x >= 0);
  return x == 0 ? 1 : x * factorial(x - 1);
}
Copy the code

The code above looks very similar to:

factorial(int x) {
  if (x >= 0) return x == 0 ? 1 : x * factorial(x - 1);
  else throw new AssertionError();
}
Copy the code

If the condition is not true, an AssertionError is thrown. The advantage of using Assert is that it is turned off in production mode and incurs no overhead in space or time. Of course, the above is just an example to show that assert, but in practice, you still need to do further verification of the situation that must be handled by using if judgment etc.

conclusion

The first article introduces common scenarios for using Dart in daily development. I’m going to do a series with Flutter (who uses Dart to develop the Web, after all, and JavaScript doesn’t smell good?). .