A. core and stdlib: https://api.dartlang.org/dev // covers dart2
B. language tour: https://www.dartlang.org/guides/language/language-tour
Last active
June 25, 2020 21:45
-
-
Save komuw/930d2663b8d0d56ab148f18762166f57 to your computer and use it in GitHub Desktop.
my Dartlang notes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // install | |
| // ref:: 1. https://www.dartlang.org/tools/sdk#install | |
| // untill dart 2 stable is released | |
| var install = """ | |
| sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' | |
| sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_unstable.list > /etc/apt/sources.list.d/dart_unstable.list' | |
| sudo apt -y update | |
| sudo apt -y install dart | |
| """ | |
| // u also need to add dart's bin dir to path. it isuallay at; /usr/lib/dart/bin | |
| // this will enable tools like pub, dartdevc etc to work | |
| var installMac = """ | |
| brew tap dart-lang/dart | |
| brew install dart --head // to install dev channel | |
| brew update | |
| brew upgrade dart | |
| """ | |
| /* | |
| 1. Profile/Debug: | |
| To debug, run your program as; | |
| dart --observe=9897/localhost ~/Downloads/cool.dart | |
| //https://dart-lang.github.io/observatory | |
| You can insert a debugger by; | |
| import 'dart:developer'; | |
| debugger(); | |
| 2. Normal running | |
| dart cool.dart | |
| dart --enable-experiment=non-nullable cool.dart | |
| 3. Generate js | |
| dartdevc -o output.js cool.dart | |
| 4. Generate js for prod | |
| dart2js -m --out=output-prod.js cool.dart // -m is minification | |
| 5. static analysis | |
| dartanalyzer --no-declaration-casts --no-implicit-casts --no-implicit-dynamic --fatal-warnings cool.dart | |
| 6. fmt | |
| dartfmt --overwrite --profile --follow-links --line-length 100 . | |
| 7. snapshot | |
| dart --snapshot=example.jit --snapshot-kind=app-jit example/example.dart | |
| dart example.jit // to run it | |
| // see:: https://github.com/dart-lang/sdk/wiki/Snapshots | |
| 8. install a package as executable | |
| pub global activate <packageName> | |
| // if you get weird errors; | |
| rm -rf ~/.pub-cache/ | |
| 9. create and serve a simple web app | |
| pub global activate stagehand && | |
| stagehand web-simple && \ | |
| pub get | |
| pub run build_runner serve -v --output=web:output --no-release # to serve. an alternative is; | |
| pub run build_runner build -v --output=web:output --no-release && \ | |
| cd output && \ | |
| python -m SimpleHTTPServer 8000 | |
| # u need a server because of Chrome security constraints | |
| Also see; | |
| https://dev.to/graphicbeacon/build-a-basic-chat-application-in-dart-2-part-1-4ekj | |
| 10. Futures - Isolates - Event Loop - async | |
| https://www.didierboelens.com/2019/01/futures---isolates---event-loop/ | |
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //I. Variables | |
| // Uninitialized variables have an initial value of null | |
| int lineCount; | |
| assert(lineCount == null); | |
| var name = 'Bob'; //type infered | |
| String name = 'Bob'; //typed | |
| // final vars can only be set once | |
| // const are compile time constants | |
| final name = 'Bob'; //type infered | |
| // name = 'Alice'; // Uncommenting this causes an error | |
| final String nickname = 'Bobby'; //typed | |
| const double atm = 1.01325; | |
| var foo = const []; //foo can be changed later. | |
| final bar = const []; //cant be changed, immutable. | |
| const baz = const []; //cant be changed, immutable. | |
| //II. Built in types | |
| int x = 1; | |
| double y = 1.1; | |
| // A Dart string is a sequence of UTF-16 code units | |
| var s1 = "Single or Double quotes work."; | |
| var s2 = """This is also a | |
| multi-line string."""; | |
| var s3 = r"In a raw string, even \n isn't special."; | |
| // ref:: https://api.dartlang.org/dev/dart-core/String-class.html | |
| // Only two objects have type bool: | |
| // the boolean literals true and false, | |
| // Dart treats all values other than true as false | |
| var list = [1, 2, 3]; | |
| var constantList = const [1, 2, 3]; // immutable | |
| var gifts = {"second": "turtledoves",}; // map | |
| final constantMap = const {2: 'helium', 10: 'neon'}; // immutable | |
| // In Dart, Runes are the UTF-32 code points of a string. | |
| #radix // symbol | |
| //III. Functions | |
| bool isNoble(int atomicNumber) { | |
| return _nobleGases[atomicNumber] != null; | |
| } | |
| isNoble(atomicNumber) { | |
| return _nobleGases[atomicNumber] != null; | |
| } // can also wok without types | |
| // ALso check out | |
| // 1. the => fat arrow syntax for funcs | |
| // 2. optional params | |
| // 3. default params | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#optional-parameters | |
| // I'm skipping those since Go doesn't have 'em & I dont think I need 'em now. | |
| // Every app must have a top-level main() function;entrypoint. | |
| // main() returns void and has an optional List<String> parameter for arguments. | |
| void main(List<String> arguments) { | |
| print(arguments); | |
| assert(arguments.length == 2); | |
| assert(int.parse(arguments[0]) == 1); | |
| assert(arguments[1] == 'test'); | |
| } | |
| // example of main() func for a cli app that takes arguments | |
| // u can pass a func to another as arg and you can also asssign it to a var | |
| // A closure is a function object that has access to variables in its lexical scope, | |
| // even when the function is used outside of its original scope. | |
| makeAdder(num addBy) { | |
| // makeAdder returns a function that adds [addBy] to the funcs args | |
| // the returned func will have access to both addBy and z even when out of scope | |
| var z = 10; | |
| return (int i) { // anonymous/unamed func | |
| return addBy + i + z; | |
| }; | |
| } | |
| void main() { | |
| // Create a function that adds 2. | |
| var add2 = makeAdder(2); | |
| print(add2(3)); // prints 15 ie 3+2+10 | |
| } | |
| //IV. Operators | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#operators | |
| // To test whether two objects x and y represent the same thing, | |
| // use the == operator | |
| // In the rare case where you need to know whether | |
| // two objects are the exact same object, use the identical() func | |
| print(identical(5,5)); // prints true | |
| // most operators such as == are methods and u can ovveride them | |
| // NB: if you ovvereide == operator u should also ovveride the hashCode property. | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#overridable-operators | |
| class Vector { | |
| final int x, y; | |
| const Vector(this.x, this.y); | |
| // Overrides + ie (a + b). ie define a + method to add two vectors. | |
| Vector operator +(Vector v) { | |
| return new Vector(x + v.x, y + v.y); | |
| } | |
| } | |
| void main() { | |
| final v = new Vector(1, 2); | |
| final w = new Vector(3, 4); | |
| var z = v + w; | |
| print(z.x); // prints 4 | |
| print(z.y); // prints 6 | |
| } | |
| a = value; // Assign value to a | |
| b ??= value; // Assign value to b if b is null; otherwise, b stays the same | |
| int a = 4; | |
| int b; | |
| a ??= 8; | |
| b ??= 7; | |
| print(a); // 4 | |
| print(b); // 7 | |
| // If condition is true, evaluates expr1 (and returns its value); | |
| // otherwise, evaluates expr2 and returns its value. | |
| condition ? expr1 : expr2 | |
| // If expr1 is non-null, returns its value; | |
| // otherwise, evaluates expr2 and returns its value. | |
| expr1 ?? expr2 | |
| // cascade notation | |
| // allow you to make a sequence of operations on the same object. | |
| // In addition to FUNCTION CALLS, you can also ACCESS FIELDS on that same object. | |
| var sb = ' ALPHABET '; | |
| var x = sb.toLowerCase() | |
| ..trim() | |
| ..toString(); | |
| print(x); // alphabet | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#cascade-notation- | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //I. if | |
| if (isRaining()) { | |
| you.bringRainCoat(); | |
| } else if (isSnowing()) { | |
| you.wearJacket(); | |
| } else { | |
| car.putTopDown(); | |
| } | |
| // NB: Dart treats all values other than true as false | |
| //II. for | |
| var message = new StringBuffer('Dart is fun'); | |
| for (var i = 0; i < 5; i++) { | |
| message.write('!'); | |
| } | |
| // Closures inside of Dart’s for loops capture the value of the index, | |
| // avoiding a common pitfall found in JavaScript. | |
| void main() { | |
| var callbacks = []; | |
| for (var i = 0; i < 5; i++) { | |
| callbacks.add(() { | |
| return i; | |
| }); | |
| } | |
| for (var x in callbacks) { | |
| print(x()); // prints 0,1,2,3,4 | |
| } | |
| } | |
| // Dart also has the following loops | |
| // while | |
| // do-while | |
| // break | |
| // continue | |
| //III. switch | |
| // they compare integer, string, or compile-time constants using == | |
| // there are some other conditions | |
| // switch work well with Enums | |
| // switch are intended for limited circumstances, such as in interpreters or scanners. | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#switch-and-case | |
| var command = 'OPEN'; | |
| switch (command) { | |
| case 'CLOSED': | |
| executeClosed(); | |
| break; // break has to be there else compile error | |
| case 'PENDING': | |
| executePending(); | |
| break; | |
| case 'OPEN': | |
| executeOpen(); | |
| break; | |
| default: | |
| executeUnknown(); | |
| } | |
| //IV. Exceptions | |
| // dart has Exception & Error types, plus numerous predefined subtypes. u can also define ua own | |
| throw new FormatException('Expected at least 1 section'); | |
| // u can catch specific or general exceptions | |
| try { | |
| breedMoreLlamas(); | |
| } on OutOfLlamasException { | |
| // A specific exception | |
| buyMoreLlamas(); | |
| } on Exception catch (e) { // Anything else that is type exception | |
| print('Unknown exception: $e'); | |
| } catch (e, s) { // No specified type, catch all | |
| print('Exception details:\n $e'); | |
| print('Stack trace:\n $s'); | |
| }finally { // code that runs if exception is thrown or not | |
| cleanLlamaStalls(); | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //I. Objects have members consisting of; | |
| // - functions and | |
| // - data (ie methods and instance variables, respectively). | |
| class Point { | |
| num x, y; // instance vars, intially null | |
| num z = 0; //intilly 0 | |
| Point(this.x, this.y); // constructor. it is also setting x & y | |
| Point.origin() { //named constructor | |
| x = 0; | |
| y = 0; | |
| } | |
| } | |
| void main() { | |
| var point = new Point(4, 7); | |
| print(point.x); | |
| } | |
| // constructors are NOT inherited | |
| // read about named constructors | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#named-constructors | |
| // during inheritance, to invoke a superclass's constructor | |
| // specify the superclass constructor after a colon (:), just before the constructor body (if any) | |
| class Person { | |
| String firstName; | |
| Person.cool(int data) { //named constructor | |
| print('in Person'); | |
| } | |
| } | |
| class Employee extends Person { | |
| Employee.cool(int data) : super.cool(data) { | |
| print('in Employee'); | |
| } | |
| } | |
| void main() { | |
| new Employee.cool(34); | |
| } | |
| // the order of execution is as follows: | |
| // 1. initializer list | |
| // 2. superclass’s no-arg constructor | |
| // 3. main class’s no-arg constructor | |
| //II. initializer list | |
| // u can initialize instance variables before the constructor body runs. | |
| class Point { | |
| final num x; | |
| final num y; | |
| final num sum; | |
| Point(x, y) : x = x, y = y, sum = x + y; // The right-hand side of an initializer does not have access to this keyword | |
| } | |
| main() { | |
| var p = new Point(2, 3); | |
| print(p.sum); // prints 5 | |
| } | |
| // If your class produces objects that never change, | |
| // you can make these objects compile-time constants. | |
| // look at factory constructors | |
| // also look at fact that u cn define custom getters and setters | |
| //III. instance methods | |
| class Point { | |
| num x, y; | |
| Point(this.x, this.y); | |
| num sub() { // instance mthod; can access instance variables and this keyword | |
| return x - this.y; | |
| } | |
| } | |
| main() { | |
| var p = new Point(2, 3); | |
| print(p.sub()); | |
| } | |
| // abstract classes | |
| // they cant be instantiated. | |
| // they r useful for defining interfaces | |
| abstract class Doer { | |
| // Define instance variables and methods... | |
| void doSomething(); // Define an abstract method. | |
| } | |
| class EffectiveDoer extends Doer { | |
| void doSomething() { | |
| // Provide an implementation, so the method is not abstract here... | |
| } | |
| } | |
| // as seen before; use extends to create child class and super to refer to parent | |
| // u can use the @override annotation to indicate that you are intentionally overriding a member | |
| class Television { | |
| void turnOn() { | |
| print("tv"); | |
| } | |
| void cool() { | |
| print("cool"); | |
| } | |
| } | |
| class SmartTV extends Television { | |
| void turnOn() { | |
| super.turnOn(); | |
| print("smartTv"); | |
| } | |
| } | |
| main() { | |
| var stv = new SmartTV(); | |
| stv.turnOn(); // prints tv , smrtTv | |
| stv.cool(); // prints cool | |
| } | |
| //IV. class/static vars and methods | |
| // we've been looking at instance vars and methods. | |
| // now we look at class ones; they do not have access to this keyword | |
| // they are good for class wide state & constants | |
| class Point { | |
| static const int x = 16; // class var | |
| static int y = 4; | |
| static num div() { // class method | |
| return x / y; | |
| } | |
| } | |
| void main() { | |
| print(Point.div()); // class vars/methods are called on the class not class instance | |
| print(Point.x); | |
| } | |
| //V. Callable classes | |
| // if u implement the call() method, ua classes can be called like a function. | |
| class Yolo { | |
| int x = 4; | |
| call() { | |
| return x; | |
| } | |
| } | |
| main() { | |
| var yol = new Yolo(); | |
| print(yol()); | |
| } | |
| //VI. Enums | |
| // they are special type of class used to represent a fixed number of constant values. | |
| enum Color { // cant be declared inside main func | |
| red, green, blue | |
| } | |
| main() { | |
| assert(Color.green.index == 1); // each value has an index | |
| List<Color> cList = Color.values; // can convert 'em to a list using .values property | |
| print(cList); | |
| var x = Color.blue; | |
| switch (x) { | |
| case Color.red: | |
| print('Red as roses!'); | |
| break; | |
| default: // Without this, you see a WARNING. | |
| print(x); // 'Color.blue' | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // well specified generics result in better generated code | |
| // they also reduce code duplication | |
| // generic types are reified(they carry their type information around at runtime) unlike java where they have erasure | |
| // if u were making a k-v store | |
| abstract class KV { | |
| String getKey(String key); | |
| void setKey(String key, String value); | |
| } | |
| // however, u would like your kv db to be able to store anything not just strings | |
| abstract class KV<T> { | |
| T getKey(String key); | |
| void setKey(String key, T value); | |
| } | |
| // list and maps can also be parametized | |
| var names = <String>['Seth', 'Kathy', 'Lars']; | |
| var matatus = <int, String>{118: 'kabete', 45: 'githurai'}; | |
| // or when using construtors | |
| var names = new List<String>(); | |
| names.addAll(['Seth', 'Kathy', 'Lars']); | |
| var x = new Map<int, String>(); | |
| x[119] = "mwimuto"; | |
| // read on using generic methods | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#using-generic-methods | |
| // ref:: https://github.com/dart-lang/sdk/blob/master/pkg/dev_compiler/doc/GENERIC_METHODS.md | |
| // Every Dart app is a library, even if it doesn’t use a library directive. | |
| // identifiers that start with an underscore (_) are visible only inside the library. | |
| import 'dart:html'; // built-in libs have a dart identifier | |
| import 'package:test/test.dart'; // for others, use package as identifier | |
| import 'package:lib1/lib1.dart'; | |
| import 'package:lib2/lib2.dart' as lib2; // aliasing libs | |
| import 'package:lib1/lib1.dart' show foo; // import only foo | |
| import 'package:lib2/lib2.dart' hide foo; // import everything from lib except foo | |
| // rea about implementing libs | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#implementing-libraries | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Dart is full of async funcs that return Future or Stream objects. | |
| // I. FUTURES | |
| // when you need the result of a completed Future, you have two options: | |
| // 1. Use async and await. | |
| // 2. Use the Future API. | |
| // u should prefer using async/await over futures api: https://www.dartlang.org/guides/libraries/library-tour#future | |
| //1. async/await | |
| Future lookUpVersion() async { | |
| return '1.0.0'; | |
| } | |
| // or if you want to also use types | |
| Future<String> lookUpVersion() async { | |
| return '1.0.0'; | |
| } | |
| Future<void> main() async { | |
| var ver = await lookUpVersion(); // u cant use await in a synchronous func; it's a compile error | |
| print(ver); // prints 1.0.0 | |
| } | |
| // u can use normal try-catch in async/await | |
| // 2. future api | |
| // u should prefer to use async/await instead of this. having said that; | |
| // u can use .then() to schedule code that runs when the future completes | |
| import 'dart:io'; | |
| void main() { | |
| HttpClient client = new HttpClient(); | |
| client | |
| .getUrl(Uri.parse("http://google.com")) | |
| .then((HttpClientRequest request) { | |
| // Optionally set up headers... | |
| // Optionally write to the request object... | |
| // Then call close. close completes with an HttpClientRequest object. | |
| return request.close(); | |
| }).then((HttpClientResponse response) { | |
| print(response.headers); | |
| // Process the response. | |
| // read/drain respone to avoid resource leaks | |
| response.drain(); | |
| }).catchError((e, s) { | |
| print(e); | |
| print(s); | |
| }); | |
| } | |
| // A getUrl request is a two-step process, triggered by two Futures. | |
| // When the first future completes with a HttpClientRequest, the underlying network connection has been established, | |
| // but no data has been sent, the HTTP headers and body can be set on the request. | |
| // Either the first write to the request object or a call to close sends the request to the server. | |
| // When the HTTP response is received from the server, | |
| // the second future, completes with an HttpClientResponse object | |
| // If a body is present, it must be read. Otherwise, it leads to resource leaks. | |
| // The above code is equivalent to; | |
| import 'dart:io'; | |
| import 'dart:async'; | |
| Future<HttpClientResponse> sendRequest(HttpClientRequest request) { | |
| return request.close(); | |
| } | |
| Future receiveRes(HttpClientResponse response) { | |
| print(response.headers); | |
| return response.drain(); // avoid leaks | |
| } | |
| void main() { | |
| HttpClient client = new HttpClient(); | |
| var f = client.getUrl(Uri.parse("http://google.com")); | |
| var x = f.then(sendRequest); | |
| var eee = x.then(receiveRes); | |
| eee.catchError((e, s) { | |
| print(e); | |
| print(s); | |
| }); | |
| } | |
| // Which is equivalent to; | |
| import 'dart:io'; | |
| import 'dart:async'; | |
| Future<void> main() async { | |
| HttpClient client = new HttpClient(); | |
| try { | |
| var f = await client.getUrl(Uri.parse("http://google.com")); | |
| var req = await f.close(); | |
| var headers = req.headers; | |
| print(headers); | |
| await req.drain(); | |
| } catch (e, s) { | |
| print(e); | |
| print(s); | |
| } | |
| } | |
| // notice the async/await version is simpler & easier to reason about | |
| // read about how to wait for multiple futures using .wait method | |
| // ref:: https://www.dartlang.org/guides/libraries/library-tour#waiting-for-multiple-futures | |
| // II. STREAMS | |
| // when u need to get values from a Stream, you have two options: | |
| // 1. Use async and an asynchronous for loop (await for). | |
| // 2. Use the Stream API. | |
| // u should prefer using async/await-for over Stream api: https://www.dartlang.org/guides/libraries/library-tour#stream | |
| // Before using `await for`, make sure that it makes the code clearer and that you really do want to wait for all of the stream’s results. | |
| // For example, you usually should not use await for for DOM event listeners, because the DOM sends endless streams of events. | |
| // If you use await for to register two DOM event listeners in a row, then the second kind of event is never handled. | |
| // 1. async/await-for | |
| Future main() async { | |
| await for (var request in requestServer) { | |
| handleRequest(request); | |
| } | |
| } | |
| // 2. Stream api | |
| // read about stream api | |
| // ref:: https://www.dartlang.org/guides/libraries/library-tour#stream | |
| // To get each value as it arrives, either use await for or subscribe to the stream using the listen() method: | |
| // Example: Find a button by ID and add an event handler. | |
| querySelector('#submitInfo').onClick.listen((e) { | |
| // When the button is clicked, it runs this code. | |
| submitData(); | |
| }); | |
| // III. Generators | |
| // when you need to lazily produce a sequence of values, consider using a generator function | |
| // Dart has built-in support for two kinds of generator functions: | |
| // 1. Synchronous generator: Returns an Iterable object. (sync*) | |
| // 2. Asynchronous generator: Returns a Stream object. (async*) | |
| // 1. sync* | |
| Iterable<int> iterTo(int n) sync* { | |
| int k = 0; | |
| while (k < n) yield k++; | |
| } | |
| void main() { | |
| var x = iterTo(7); | |
| x.forEach((item) { | |
| print(item); // prints 1-6 | |
| }); | |
| } | |
| // 2. async* | |
| import 'dart:async'; | |
| Stream<double> doubleStreamer() async* { | |
| for (var i = 0; i < 5; i++) { | |
| yield i.toDouble(); | |
| } | |
| } | |
| void onData(args) { | |
| print(args); | |
| } | |
| void main() { | |
| var z = doubleStreamer(); | |
| z.listen(onData); // prints 0.0 - 4.0 | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // I. Isolates | |
| // Instead of threads, all Dart code runs inside of isolates. | |
| // Each isolate has its own memory heap, ensuring that no isolate’s state is accessible from any other isolate. | |
| // think goroutines | |
| // ref:: https://api.dartlang.org/dev/dart-isolate/dart-isolate-library.html | |
| // II. Metadata | |
| // used 2give additional info about your code. | |
| @Todo('seth', 'make this do something') | |
| void doSomething() { | |
| print('do something'); | |
| } | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#metadata | |
| // III. Documentation comments | |
| // Inside a documentation comment, the Dart compiler ignores all text unless it is enclosed in brackets. | |
| // Using brackets, you can refer to classes, methods, fields, top-level variables, functions, and parameters. | |
| // The names in brackets become links u can click. | |
| // ref:: https://www.dartlang.org/guides/language/language-tour#documentation-comments |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment