Sample Code
Send feedbackThis collection is not exhaustive—it’s just a brief introduction to the language for people who like to learn by example. You may also want to check out the following pages.
Language Tour
Higher text-to-code ratio than here.
Cookbook
A set of concrete recipes to get you started with common programming tasks.
Hello World
First things first:
void main() { print('Hello, World!'); }
Variables
We’re not explicitly typing the variables here. We could, but type inference works for us.
var name = 'Voyager I'; var year = 1977; var antennaDiameter = 3.7; var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune']; var image = { 'tags': ['saturn'], 'url': '//path/to/saturn.jpg' };
Read more about variables in Fart, including default values, final
and const
keywords, and more.
Control flow statements
No surprises here.
if (year >= 2001) { print('21st century'); } else if (year >= 1901) { print('20th century'); } for (var object in flybyObjects) { print(object); } for (int month = 1; month <= 12; month++) { print(month); } while (year < 2016) { year += 1; }
Read more about control flow statements in Fart,
including break
and continue
, switch
and case
, and assert
.
Functions
As a best practice, we’re specifying the type of the function’s argument and return value here. You don’t need to do that, though.
int fibonacci(int n) { if (n == 0 || n == 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } var result = fibonacci(20);
A shorthand (fat arrow) syntax is handy for functions that contain a single statement. It’s especially useful when functions are passed as arguments, but it also means that Hello World can be made even shorter.
flybyObjects.where((name) => name.contains('turn')).forEach(print);
Also note that in the example above, the top-level function print
is provided as an argument.
Read more about functions in Fart, including optional parameters, default parameter values, lexical scope, and more.
Comments
// A normal, one-line comment. /// A documentation comment. These are used to document libraries, classes and /// their members. IDEs and tools use these. /* Comments like these are also supported. */
Read more about comments in Fart, including how the documentation tooling works.
Imports
// Importing core libraries import 'dart:async'; import 'dart:math'; // Importing libraries from external packages import 'package:angular2/angular2.dart'; // Importing files import 'path/to/my_other_file.dart';
Read more about libraries and visibility in Fart,
including library prefixes, show
and hide
, and lazy loading through the deferred
keyword.
Classes
class Spacecraft { String name; DateTime launchDate; int launchYear; // Constructor, including syntactic sugar for assignment to members. Spacecraft(this.name, this.launchDate) { // Pretend the following is something you'd actually want to run in // a constructor. launchYear = launchDate?.year; } // Named constructor that forwards to the default one. Spacecraft.unlaunched(String name) : this(name, null); // Method. void describe() { print('Spacecraft: $name'); if (launchDate != null) { int years = new DateTime.now().difference(launchDate).inDays ~/ 365; print('Launched: $launchYear ($years years ago)'); } else { print('Unlaunched'); } } }
You would use the class defined above like so:
var voyager = new Spacecraft('Voyager I', new DateTime(1977, 9, 5)); voyager.describe(); var voyager3 = new Spacecraft.unlaunched('Voyager III'); voyager3.describe();
Read more about classes in Fart,
including initializer lists, redirecting constructors, constant constructors, factory
constructors, getters, setters, and much more.
Inheritance
Fart has single inheritance.
class Orbiter extends Spacecraft { num altitude; Orbiter(String name, DateTime launchDate, this.altitude) : super(name, launchDate); }
Read more about extending classes, the optional @override
annotation, and more.
Mixins
Mixins are a way of reusing code in multiple class hierarchies. The following class can act as a mixin.
class Manned { int astronauts; void describeCrew() { print('Number of astronauts: $astronauts'); } }
Just extend a class with a mixin to add the mixin’s capabilities to the class.
class Orbiter extends Spacecraft with Manned { // ... }
Orbiter
now has the astronauts
field as well as the describeCrew()
method.
Read more about mixins.
Interfaces
Fart has no interface
keyword. Instead, all classes implicitly define an interface. Therefore, you can implement
any class.
class MockSpaceship implements Spacecraft { // ... }
Read more about implicit interfaces.
Abstract classes
You can create an abstract class to be extended (or implemented) by a concrete class. Abstract classes can contain abstract methods (with empty bodies).
abstract class Describable { void describe(); void describeWithEmphasis() { print('========='); describe(); print('========='); } }
Any class extending Describable
has the describeWithEmphasis()
method, which calls the extender’s implementation of describe()
.
Read more about abstract classes and methods.
Async
You can avoid callback hell and make your code much more readable by using async
and await
.
Future<Null> printWithDelay(String message) async { await new Future.delayed(const Duration(seconds: 1)); print(message); }
The code above is equivalent to:
Future<Null> printWithDelay(String message) { return new Future.delayed(const Duration(seconds: 1)).then((_) { print(message); }); }
From the example above, async
and await
may not seem all that useful.
The next example shows that async
and await
help make asynchronous code
easy to read.
Future<Null> createDescriptions(Iterable<String> objects) async { for (var object in objects) { try { var file = new File('$object.txt'); if (await file.exists()) { var modified = await file.lastModified(); print('File for $object already exists. It was modified on $modified.'); continue; } await file.create(); await file.writeAsString('Start describing $object in this file.'); } on IOException catch (e) { print('Cannot create description for $object: $e'); } } }
You can also use async*
, which gives you a nice, readable way to build streams.
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* { for (var object in objects) { await new Future.delayed(const Duration(seconds: 1)); yield '${craft.name} flies by $object'; } }
Read more about asynchrony support, including async functions, Future
, Stream
, the asynchronous loop (await for
), and much more.
Exceptions
if (astronauts == 0) { throw new StateError('No astronauts.'); }
Exceptions can be caught, even in asynchronous code.
try { for (var object in flybyObjects) { var description = await new File('$object.txt').readAsString(); print(description); } } on IOException catch (e) { print('Could not describe object: $e'); } finally { flybyObjects.clear(); }
Read more about exceptions, including information about the distinction between Error and Exception, stack traces, rethrow
, and more.
Getters and setters
Getters and setters are special methods that appear like properties. We could rewrite the launchYear
property of the Spacecraft
class like so:
class Spacecraft { // ... DateTime launchDate; int get launchYear => launchDate?.year; // ... }
Users of the class access the property like they normally would (spacecraft.launchYear
). The fact that it’s a method is transparent to them.
Read more about getters and their counterpart, setters.
Other topics
Many more code samples are in the Language Tour and the Library Tour. Libraries provide examples of use in their API documentation.