original

https://betterprogramming.pub/7-cool-features-of-dart-language-809608371e28

refer to

text

Today's article briefly reveals the cool features provided by the Dart language. More often, these options are unnecessary for simple applications, but are a lifesaver when you want to improve your code through simplicity, clarity, and conciseness.

With that in mind, let's go.

Cascade

Cascades ( .. , ?.. ) allow you to perform a series of operations on the same object. This often saves the step of creating temporary variables and allows you to write more fluent code.

 var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;

//above block of code when optimized
var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

Abstract abstract class

Use the abstract modifier to define an _abstract abstract class (a class that cannot be instantiated). Abstract classes are useful for defining interfaces, usually with some implementation.

 // This class is declared abstract and thus
// can't be instantiated.
abstract class AbstractContainer {
  // Define constructors, fields, methods...

  void updateChildren(); // Abstract method.
}

Factory constructors

Use the factory keyword when implementing a constructor that does not always create a new instance of a class.

 class Logger {
  String name;
  Logger(this.name);
  factory Logger.fromJson(Map<String, Object> json) {
    return Logger(json['name'].toString());
  }
}

Named named constructor

Use named constructors to implement multiple constructors for a class or to provide additional clarity:

 class Points {
  final double x;
  final double y;

  //unnamed constructor
  Points(this.x, this.y);

  // Named constructor
  Points.origin(double x,double y)
      : x = x,
        y = y;

  // Named constructor
  Points.destination(double x,double y)
      : x = x,
        y = y;
}

Mixins

Mixins are a way to reuse class code across multiple class hierarchies.

To implement the implement mixin, create a class that declares no constructor. Use the mixin keyword instead of a class unless you want mixin to be available as a regular class.

To use a mixin, use the with keyword followed by one or more mixin names.

To limit the types of mixins that can be used, use the on keyword to specify the desired superclass.

 class Musician {}

//creating a mixin
mixin Feedback {
  void boo() {
    print('boooing');
  }

  void clap() {
    print('clapping');
  }
}

//only classes that extend or implement the Musician class
//can use the mixin Song
mixin Song on Musician {
  void play() {
    print('-------playing------');
  }

  void stop() {
    print('....stopping.....');
  }
}

//To use a mixin, use the with keyword followed by one or more mixin names
class PerformSong extends Musician with Feedback, Song {
  //Because PerformSong extends Musician,
  //PerformSong can mix in Song
  void awesomeSong() {
    play();
    clap();
  }

  void badSong() {
    play();
    boo();
  }
}

void main() {
  PerformSong().awesomeSong();
  PerformSong().stop();
  PerformSong().badSong();
}

Typedefs

Type aliases — a concise way of referring to a type. Typically used to create custom types that are frequently used in projects.

 typedef IntList = List<int>;
List<int> i1=[1,2,3]; // normal way.
IntList i2 = [1, 2, 3]; // Same thing but shorter and clearer.

//type alias can have type parameters
typedef ListMapper<X> = Map<X, List<X>>;
Map<String, List<String>> m1 = {}; // normal way.
ListMapper<String> m2 = {}; // Same thing but shorter and clearer.

Extension extension method

Introduced in Dart 2.7, extension methods are a way to add functionality to existing libraries and code.

 //extension to convert a string to a number
extension NumberParsing on String {
  int customParseInt() {
    return int.parse(this);
  }

  double customParseDouble() {
    return double.parse(this);
  }
}

void main() {
  //various ways to use the extension

  var d = '21'.customParseDouble();
  print(d);

  var i = NumberParsing('20').customParseInt();
  print(i);
}

optional positional arguments

Positional parameters can be made optional by wrapping them in square brackets. Optional positional arguments are always last in the function's argument list. They default to null unless you provide another default value.

 String joinWithCommas(int a, [int? b, int? c, int? d, int e = 100]) {
  var total = '$a';
  if (b != null) total = '$total,$b';
  if (c != null) total = '$total,$c';
  if (d != null) total = '$total,$d';
  total = '$total,$e';
  return total;
}

void main() {
  var result = joinWithCommas(1, 2);
  print(result);
}

unawaited_futures

When you want to start a Future , the recommended way is to use unawaited

Otherwise, if you don't add async, it will not execute.

 import 'dart:async';

Future doSomething() {
  return Future.delayed(Duration(seconds: 5));
}

void main() async {
  //the function is fired and awaited till completion
  await doSomething();

  // Explicitly-ignored
  //The function is fired and forgotten
  unawaited(doSomething());
}

end.


© Cat Brother


独立开发者_猫哥
669 声望129 粉丝