En liten playground för att testa på grunderna i språket Dart.
Provkör med dartpad.dev.
| // ignore_for_file: unused_local_variable | |
| // ignore_for_file: avoid_function_literals_in_foreach_calls | |
| // ignore_for_file: unnecessary_type_check | |
| // ignore_for_file: unnecessary_new | |
| void main() { | |
| variables(); | |
| strings(); | |
| controlFlow(); | |
| operators(); | |
| functions(); | |
| collections(); | |
| classes(); | |
| castingAndTypeChecking(); | |
| soundNullSafety(); | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Variables ----------------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See more: | |
| /// * https://dart.dev/guides/language/language-tour#variables | |
| void variables() { | |
| /// Mutable variable, type inferred | |
| var a = 42; | |
| a = 4711; | |
| print('a: $a'); | |
| /// Mutable variable with explicit type | |
| String b = '42'; | |
| print('b: $b'); | |
| /// Immutable "variable" with inferred type | |
| final c = DateTime.now(); | |
| //c = DateTime.parse('2021-06-08'); // Error - can only be set once | |
| print('c: $c'); | |
| /// Compile time constant, with explicit type | |
| const int d = 42; | |
| //d = 4711; // Error - constant variables can't be assigned a value | |
| print('d: $d'); | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Strings ------------------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#string-interpolation | |
| /// * https://dart.dev/guides/language/language-tour#strings | |
| void strings() { | |
| /// String literals | |
| final string1 = 'Preferred'; // Preferred according to standard Dart linting rules | |
| final string2 = "Also valid"; // Frowned upon | |
| /// Expressions in strings | |
| int theAnswer = 42; | |
| // Expressions (i.e. more than a simple variable) must be surrounded by | |
| // { and } | |
| print('The answer is $theAnswer, is that odd: ${theAnswer.isOdd}?'); | |
| /// Concatenation (not recommended) | |
| // ignore: prefer_interpolation_to_compose_strings | |
| final concatenatedString = 'The answer is ' + theAnswer.toString(); | |
| print('ConcatenatedString: $concatenatedString'); | |
| /// Multiline | |
| final multiLine = ''' | |
| Lorem ipsum | |
| Bacon ipsum | |
| Pirate ipsum | |
| '''; | |
| print('MultiLine: $multiLine'); | |
| /// Raw string | |
| final raw = r'Lorem ipsum\nBacon ipsum\nPirate ipsum'; | |
| print('Raw: $raw'); | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Control flow -------------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/guides/language/language-tour#control-flow-statements | |
| void controlFlow() { | |
| final args = ['a', 'b', 'c', 'd', 'e']; | |
| assert(args.isNotEmpty); // Throws error in debug mode | |
| if (args.length < 4) { | |
| // Expression must be of type bool (unlike JS for instance) | |
| switch (args.length) { | |
| case 1: // Fall through | |
| case 2: | |
| print('1 or 2'); | |
| break; | |
| case 3: | |
| print('Third time is the charm'); | |
| break; | |
| default: | |
| print('Default'); | |
| } | |
| } else { | |
| for (var arg in args) { | |
| print(arg); | |
| } | |
| for (var i = 0; i < 10; i++) { | |
| print('☀️'); | |
| } | |
| } | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Operators ----------------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/guides/language/language-tour#operators | |
| class SomeBuilder { | |
| var someField = ''; | |
| void configureStuff() {/**/} | |
| } | |
| void operators() { | |
| /** The usual suspects, and some more interesting stuff: **/ | |
| /// Null coalescing | |
| String? oprionalString; | |
| var result = oprionalString ?? 'Default'; | |
| /// Spead operator | |
| final list = ['Austin', 'Dr Evil']; | |
| var more = [...list, 'Number Two']; | |
| /// Builder / cascade operator | |
| final builder = SomeBuilder() | |
| ..configureStuff() | |
| ..someField = 'stuff'; | |
| } | |
| /// ------------------------------------------------- | |
| /// *** Functions *** | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/guides/language/language-tour#functions | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#optional-positional-parameters | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#named-parameters | |
| void plainOldFunction() {/* body */} | |
| /// Arrow function | |
| void arrowFunc() => 'The result'; | |
| /// Anonymous function / lambda / closure | |
| var lambda1 = (int arg) => 'The answer is: $arg'; | |
| var lambda2 = (int arg) { | |
| return 'The answer is: $arg'; | |
| }; | |
| /// Function with positional arguments | |
| void functionWithArgs1(String arg1, bool arg2) {/* body */} | |
| /// Function with optional positional arguments | |
| void functionWithArgs2(String arg1, [bool? arg2]) {/* body */} | |
| /// Function with positional and named arguments | |
| void functionWithArgs3(String arg1, {bool? arg2}) {/* body */} | |
| /// Function with named arguments and default values | |
| void functionWithDefaultValues({String arg1 = '', bool arg2 = false}) {/* body */} | |
| void functions() { | |
| functionWithArgs1('', false); | |
| functionWithArgs2(''); | |
| functionWithArgs3('', arg2: true); | |
| functionWithDefaultValues(arg1: 'Hello', arg2: true); | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Collections --------------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/guides/language/language-tour#lists | |
| /// * https://dart.dev/guides/language/language-tour#maps | |
| /// * https://dart.dev/guides/language/language-tour#sets | |
| /// * https://dart.dev/guides/language/language-tour#using-collection-literals | |
| /// * https://dart.dev/guides/language/language-tour#generic-collections-and-the-types-they-contain | |
| void collections() { | |
| /// List declaration | |
| List<String> list; | |
| /// List literal | |
| list = ['Hello', 'World']; | |
| /// Some list functions | |
| list.add('!!!'); | |
| list.first; | |
| list.indexOf('Hello'); | |
| list.join(' '); | |
| listHigherOrderFunctions(list); | |
| /// Map declaration | |
| Map<String, int> map; | |
| /// Map literal | |
| map = {'The answer': 42}; | |
| /// Some map functions | |
| map['The answer']; | |
| map['The answer'] = 4711; | |
| map.containsKey('key'); | |
| map.keys.first; | |
| /// Set declaration | |
| Set<String> set; | |
| /// Set literal | |
| set = {'Hello', 'World'}; | |
| /// Some set functions | |
| set.add('!!!'); | |
| set.contains('Hello'); | |
| set.first; | |
| } | |
| void listHigherOrderFunctions(List<String> list) { | |
| /// Find an element/// Often called 'find' in other languages | |
| list.firstWhere((element) => element == 'Hello'); | |
| /// Iterate over elements | |
| list.forEach((element) => print(element)); | |
| /// Created a new filtered list/// Often called 'filter' in other languages | |
| list.where((element) => false); | |
| /// Created a new list with transformed elements | |
| list.map((element) => element.toUpperCase()); | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Classes and constructors -------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/guides/language/language-tour#classes | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#named-constructors | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#factory-constructors | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#redirecting-constructors | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#const-constructors | |
| class FictionalCharacter { | |
| final String name; | |
| /// Constructor, directly assigning field | |
| FictionalCharacter(this.name); | |
| } | |
| /// Create a new instance of FictionalCharacter | |
| final austin = FictionalCharacter('Austin Powers'); | |
| /// New instance optional 'new' keyword - not recommended | |
| final drEvil = new FictionalCharacter('Dr Evil'); | |
| class FictionalCharacter1 { | |
| final String name; | |
| final int _age; // Private field | |
| /// Manually assigned final field (after ':') | |
| FictionalCharacter1(this.name) : _age = 85; | |
| // 'this' refers to current instance | |
| } | |
| class FictionalCharacter2 { | |
| final String name; | |
| final String alias; | |
| /// Constructor with optional parameters | |
| FictionalCharacter2(this.name, {String? alias}) : alias = alias ?? 'Spy' { | |
| // Optional constructor body | |
| print('Watch out, here is $name!'); | |
| } | |
| /// Additional, named constructor | |
| FictionalCharacter2.coolestCharacter() | |
| : name = 'Austin Powers', | |
| alias = 'International man of mystery'; | |
| } | |
| void classes() { | |
| /// Create a new instance of FictionalCharacter | |
| final austin = FictionalCharacter1('Austin Powers'); | |
| print(austin.name); | |
| print(austin._age); // Not visible outside source file | |
| /// Using named constructor | |
| final coolest = FictionalCharacter2.coolestCharacter(); | |
| } | |
| /// *** More about classes *** | |
| /// Interface / protocol - implemented with abstract class | |
| abstract class SomeInterface { | |
| void interfaceMethod(); | |
| } | |
| /// Abstract classes can contain concrete methods | |
| abstract class SomeBaseClass { | |
| bool someField = true; | |
| void abstractMethod(); | |
| void inheritedMethod() {/* Implementation */} | |
| } | |
| /// Mixins - another way of reusing functionality | |
| mixin SomeTrait on SomeBaseClass { | |
| // Optionally limit use with 'on' | |
| bool mixedInField = true; | |
| void someUsefulMethod() {/* Implementation */} | |
| } | |
| /// Putting it to use | |
| class AwesomeClass extends SomeBaseClass with SomeTrait implements SomeInterface { | |
| @override | |
| void interfaceMethod() {/* Implementation */} | |
| @override | |
| void abstractMethod() {/* Implementation */} | |
| } | |
| /// *** Casting and type checking *** | |
| void castingAndTypeChecking() { | |
| Object austin = FictionalCharacter('Austin'); | |
| /// Will throw exception if invalid | |
| var name = (austin as FictionalCharacter).name; | |
| /// Safer | |
| if (austin is FictionalCharacter) { | |
| var name = austin.name; | |
| } | |
| } | |
| /// ------------------------------------------------- | |
| /// --- Sound null safety --------------------------- | |
| /// ------------------------------------------------- | |
| /// | |
| /// See also: | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#nullable-variables | |
| /// * https://dart.dev/codelabs/dart-cheatsheet#null-aware-operators | |
| void soundNullSafety() { | |
| // String string = null; // INVALID in null-safe Dart. | |
| /// Null safety is enabled by default in Dart. | |
| /// '?' is used to mark nullable types. | |
| String? string; | |
| print(string?.length); // prints 'null' | |
| if (string != null) { | |
| print(string.length); // '?' no longer needed | |
| } | |
| string ??= 'Hello'; // Assign if null | |
| } | |
| class LazyClass { | |
| late final int myInt; | |
| LazyClass() { | |
| myInt = 42; | |
| } | |
| } |