0 ratings0% found this document useful (0 votes) 1K views97 pagesLanguage Tour - Dart PDF
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
A Tour of the Dart Language
This page shows you how to use each major Dart feature, from variables and operators to classes and libraries, with the assumption
that you already know how to program in another language.
To learn more about Dar's core libraries, ee A Tour ofthe Dart Libraries (/guidesylibraries/library-tour)
Note: You can play with most ofthese features using DartPad (/tools/dartpad).
Consult the Dart Language Specification /guides/language/spec) whenever you want more details about a language feature.
A basic Dart program
The fllowing code uses many of Darts most basic features:
U1 define a function.
printNunber(num aNunber) {
print (‘The number is SaNumber
y
5 // Print to console.
U1 This is where the opp starts executing
pain() {
var nunber = 42; // Declare and initialize a variable.
printNumber (number); // Calta function.
yopen Drtpad
Here's what this programuses that apps oar almost al Da 3p
11 This « coment.
Use//t indicate thal there of theline sa comment. leat se. "For dtl se Comments,
Atpe. ome of te otherbltin types ae Sing it and boo
a
‘Anumber literal, Number literals are a kind of compile-time constant
print()
handy way to display output,
)
“(or
Astring literal
$SvariabLeNane (or ${expression})
String interpolation: including a variable or expression’s string equivalent inside of a string literal. For more information, see Strings.
rain()
The special, required, top-level function where app execution starts, Far more information, see The main\) function,
Away to declare a variable without specifying its type.
Note: Our code follows the conventions in the Dart style guide (/guides/language/effective-dart/styl). For example, we use two-
space indentation,
Important conceptsAs you learn about the Dart language, Keep these facts and concepts in mind:
Everything you can place ina variable’ an object, and every objects an instance of a class. Even numbers, functions, and null
are objects, All objects inherit from the Object™ clas.
Specifying static types (such as num in the preceding example) clarifies your intent and enables static checking by tools, (You
‘might notice when you're debugging your code that variables with no specified type get a special type: dynamic.) Specifying static
types is optional in Dart 1.x, however Dart is moving towards being 2 fully type safe language,
Instrong mode (/guides/language/sound-dart, static and runtime checks ensure that your code is type safe, helping you catch
bugs in development, rather than at runtime. Strong mode is optional in Dart 1.x, but nat optional in Dart 2.0 (/dart-2.0).
Dart parses all your code before runningit. You can provide tips to Dart—for example, by using types or compile-time constants—
[Link] errors or help your code run faster,
Dart supports top-Ievel functions (such as main()), as well as functions tied toa class or objec (staticand instance methods,
respectively). You can also create functions within functions (nested or local functions
Similarly, Dart supports top-level variables, as well as variables tied toa class or objec (static and instance variables). Instance
variables are sometimes known as fields or properties
Unlike Java, Dart doesn't have the keywords public, protected, and private. If an identifier starts with an underscore (), it's
private to its library. For details, see Libraries and visibility
Identifierscan start mith a letter or, followed by any combination of those characters plus digi
‘Sometimes it matters whether something_is an expression ora statement, o we'll precise about those two words.
Dart tools can report two kinds of problems: warnings and errors. Warnings are just indications that your code might not work,
but they don’t prevent your program from executing. Errors can be either compile-time or run-time. A compile-time error
prevents the code from executing at all, run-time error results in an exception being raised while the code executes.
Dart [Link] two runtime modes: production and checked. We recommend that you develop and debug in checked mode, and
deploy to production mode. Productian modes the default runtime mode of 2 Dart program, optimized for speed. Production
‘mode ignores assert statements and static types. Checked modeis a developer-friendly made that helps you catch some type
errors during runtime. For example, ifyou assign 2 non-number toa variable declared as a nun, then checked mode throws an
exceptionDart 2.0 note: Checked mode won't be in Dart 2.0, For more information, see Dart 2.0 Updates. (/dart-2.0}
Keywords
The following table lsts the words that the Dart language treats specially.
abstract?
assert
async?
asynct?
await?
break
catch
class
const
continue
covariant»
éefault
deferred
do
dynamic?
else
export!
external?
extends
factory
false
final
finally
for
eet?
it
implements?
import?
Ubrary?
ll
operator!
part
rethrow
return
set?
static!
super
switch
sync*?
this
throw
tue
wy
typedef!
void
while
with
yield?
yield?Words withthe superscript are built-in identifiers, Avoid using built-in identifiers as identifier. A compile-time error happensi you
try touse a built-in identifier for a class or type name.
2 Words withthe superscript2 are never, limited reserved words related to asynchrony support added after Darts 1.0 release, You
can’t use async, axait, or yield as an identifier in any function body marked with asyne, async, or sync, For more information, see
synchrony support.
Allother words in the keyword table are reserved words. You can't use reserved words as identifiers.
Variables
Here's an example of creating a variable and assigning value to it
var name = “Bob*;
Variables are references. The variable called nane contains a reference toa String object with 2 value of “Bob”,
Default value
Uninitialized variables have an initial value of nuld. Even variables with numeric types are intially null, because numbers are objects
int Linecount;
assert(lineCount == null);
U1 Variables (even if they wiLl be numbers) are initially null
Note: The assert() cals ignored in production mode. In checked mode, assert(condition) throws an exception unless
conditionis true, For details, see the Assert section.
Dart 2.0 note: Checked mode won't be in Dart 2.0, For more information, see Dart 2.0 Updates. (/dart-2.0]Optional types
Dart 2.0 note: Types won't be optional in Dart 2.0, but you'l still be able to omit some type annotations, thanks to type inference,
For more information, see Dart 2.0 Updates. /dart-2.0)
You have the option of adding static types to your variable declarations:
String name
*aob's
[Adding typesis a way to clearly express your intent. Tools such as compilers and editors can use these types te help you, by providing
code completion and early warnings for bugs and code completion.
Note: Ths page follows the style guide recommendation /guides/language/effective-dart/designstype-annotations) of using var,
rather than type annotations, for local variables. Even under strong mode (/dart-7.0), you can specify var—the analyzer infers the
type where possible.
Final and const
Ifyou never intend to change a variable, use final or const, ether instead of var orn addition toa type. A final variable can be set only
‘once; a const variable is a compile-time constant. (Const variables are implicitly final. A final top-level or clas variable is initialized the
first time it’s used,
Note: instance variables can be Final but not con:
Here's an example of creating and setting a final variable:final name = "Bob"; // Or: final String name = 'Bob';
// name = ‘Alice’; // Unconmenting this causes an error
Use const for variables that you want to be compile-time constants. Ifthe const variable is atthe class level, markt static const.
Where you declare the variable, set the value to a compile-time constant such as a number or string literal const variable, or the result
of an arithmetic operation on constant numbers:
10200005 // Unit of pressure (dynes/em2)
1.01325 * bar; // Standard atmosphere
The const keyword isn't just for declaring constant variables. You can also use it to create constant values, as well as to declare
constructors that create constant values. Any variable can have a constant value.
// Note: [] creates an empty List.
V1 const [] creates an enpty, immutable List (EIA)
var foo = const []; // foo is currently an EIA.
final bar = const []; // bar will always be an ETA.
const baz = const []; // baz is a compile-time constant EIA
// You con change the value of @ non-final, non-const variable,
U/ even if it used to have a const value.
foo = [3
// You con't change the value of a final or const variable.
U1 bar = [1]; // Unhandled exception.
U1 baz = []; // Unhandled exception.
For more information on using const to create constant values, see Lists, Maps, and Classes.
Built-in types‘The Dart language has special support for the following types:
+ numbers
+ strings
+ booleans
+ lists also known as arrays)
+ maps
+ runes (for expressing Unicode characters ina string)
+ symbols
You can initialize an object of any of these special types using aliteral. Forexample, ‘this 4s a string! isa string literal, and trues
boolean literal
Because every variable in Dart refers to an object—an instance ofa class—you can usually use constructorsto initialize variables. Some
of the builtin types have their own constructors. For example, you can use the Map() constructor to create a map, using code such as
ew *ap().
Numbers
Dart numbers come in two flavors:
int
Integer values, which generally should be in the range-2"*to 2"
double”
64-bit (dovble-precision) floating-point numbers, as specified by the IEEE 754 standard
Both int and double are subtypes of nus.” The num type includes basic operators such as ,-,/, and *, and is also where you'll find
abs(), ceil(), and #loo-(), among other methods. (Bitwise operators, such as>>, are defined in the int class.) ifnum and its
subtypes don't have what you're looking for, the dart:math™ library might:
Integers outside ofthe -2* to 2° range currently behave dferently in JavaScript produced from Dart cade than they
‘do when the same Dart code runsin the Dart VM. The reason is that Dart is specified to have arbitrary-precision integers, but
JavaScript isn't, See issue 1533" for detailIntegers are numbers without a decimal point, Here are some examples of defining integer literals:
var hex = OXDEADBEEF;
var bigint = 34653465624652437659238076592374958739845729;
la number includes a decimal, tis a double. Here are some examples of defining double literals:
var y = 1.15
var exponents = 1.42¢5;
Here's how you turn a stringinto a number, or vice versa
UW String -> int
var one = [Link](‘1");
assert(one == 1);
U1 String -> double
var onePointone = [Link]("2.1");
assert(onePointone == 1.1);
UL it -> string
String onefsstring = [Link]();
assert(oneasstring == '1');
// double -> string
String piAsstring = [Link](2) 5
assert(piasstring == '3.14");
The int type specifies the traditional bitwise shift (<<, >), AND (8), and OR ()) operators. For example:assert((3 << 1) == 6); // 081 << 1m» 0110
assert((3 >> 1) == 3); // 0012 >> 1 == 0901
assert((3 | 4) == 7); // 0012 | 6100 == 0112
Literal numbers are compile-time constants. Many arithmetic expressions are also compile-time constants, as long as their operands,
are compile-time constants that evaluate to numbers.
const msPersecond = 1608;
const secondsuntilretry = 5;
const msUntilRetry = secondsun
Retry * msPerSecond;
Strings
[Dart strings a sequence of UTF-16 code units. You can use either single or double quotes to create a string
var si = ‘Single quotes work well for string Literals.";
var s2 = "Double quotes work just as well";
var 53 = "It\'s easy to escape the string delimiter’;
var 54 = "It's even easier to use the other deliniter."s
You can put the value of an expression inside a string by using ${expression). Ifthe expression is an identi
let, you can skip the To
get the string corresponding to an abject, Dat calls the object’s tostring() method.aamaos? Language Te [Ome
var s = ‘string interpolation’;
assert(‘Dart has $5, which is very handy
Dart has string interpol
which is very handy.")
assert(‘That deserves all caps. * +
"${[Link]()} 1s very handy!" ==
“That deserves all caps. ° +
STRING INTERPOLATION {s very handy!*);
Note: The
code units
erator tests whether two objects are equivalent. Two strings are equivalent if they contain the same sequence of
You can concatenate strings using agjacent string literals or the + operator:
var si = ‘String * ‘concatenation’
works even over Line breaks."
“string concatenation works even over
“Line oreaks.");
assert(st
var s2 = "The + operator
+ ‘works, as well.*;
“The + operator works, as well.*);
assert(s2
Another way to create a multi-line string: use a triple quote with either single or double quotation marks:var st =
You can create
multi-line strings like this one.
var s2 = """This is also a
multi-line string
You can create
raw’ string by prefxing it with r
var s = r"In a raw string, even \n isn’t special.";
‘See Runes for detals on how to express Unicode characters ina string
Literal strings are compile-time constants, as long as any interpolated expression is @ compile-time constant that evaluates to null ora
numeric, string, or boolean valve.
// These work in a const string.
const aconstNun = @;
‘trues
const aConststring = 'a constant string’;
const aConstBool
U1 These do NOT work in a const string.
var aNun = 2:
var aBool = true;
var aSteing = ‘a string’;
const aConstList = const [1, 2, 3];
const validConststring
‘SaConstNun $aConstBool $aconststring’
// const invalidconststring = '$aNum $abool $astring $oConstlist’;aamaos? Language Te [Ome
For mote information on using strings, see Strings and regular expressions (/guideslibraries/library-tourdstrings-and-regular-
expressions).
Booleans
To represent boolean values, Dart has a type named bool. Only two objects have type book: the boolean literals true and false, which
are both compile-time constants.
When Dart expects a boolean value, only the value trues treated as true, Allother values are treated as false, Unlike in JavaScript,
values such as 1, "astring", and soneObject are all treated as alse
For example, consicer the following code, which is valid both as JavaScript and as Dart code:
var name = “Bob";
if (name) {
U7 Prints in Javascript, not in bart.
print("You have a nane!");
y
you run this code as JavaScript, it prints "You have a name!” because name isa non-null object. However, in Dart running in
production mode, the preceding code doesn’t print at all because nane is converted to False (becausenane I= true).In Dart running
in checked mode, the preceding code throws an exception because the nare variable is not a bool,
Dart 2.0 note: Checked mode won't be in Dart 2.0, For more information, see Dart 2.0 Updates. (/dart-2.0)
Here's another example of code that behaves diferently in JavaScript and Darta)
print (‘2S prints
p else {
print(‘bart in production node prints this line.");
71 However, in checked mode, if (1) throws an
U1 exception because 1 is not boolean.
y
iis Line.");
Note: The previous two samples work only in production mode, not checked mode. In checked mode, an exception Is thrown if
rnon-boolean is used when a boolean value is expected,
Dart’s treatment of booleans is designed to avoid the strange behaviors that can arise when many values can be treated as true. What
this means for you is that, instead of using code like if (nonbooLeanvaLue), you should instead explicitly check for values. For
example:
U1 Check for an empty string.
var fullNane = °°
assert([Link]);
U1 Check for zero.
var nitPoints = @;
assert(hitPoints <= 0);
U Check for null.
assert(unicorn =
null);
U1 Check for NaN.
var iMeantToooThis = 0 / 8;
assert(iMeant [Link]);Lists
Perhaps the most common collection in nearly every programming language isthe array, or ordered group of objects. In Dart, arrays are
List objects, so we usually just cal them lists
Dart lst literals look ike JavaScript aray literals. Here's a simple Dart ist:
var list = [1, 2, 3];
Note: f you're wondering whether this list literal is strong mode compliant (/guides/language/sound-dar) itis. Thanks to type
inference (/guides/language/sound-dartétype-inference), the analyzer infers that List has type Listcint>. Ifyou try to add non
integer objects to this list under strong mode, the analyzer raises an error.
Lists use zero-based indexing, where 0's the index ofthe frst element and list. length - 1istheindex ofthe last element. You can
getalist’s length and refer to ist elements just as you would in JavaScript
var list = [1, 2, 3];
assert([Link] == 3);
assert(List[1] == 2);
List(a} = 15
assert(list[1] == 1);
To create alist that’s a compile-time constant, add const before the list literal:
var constantList = const [1, 2, 313
UH constantlist[1] = 1; // Uncommenting this causes an error,The Listtype has many handy methods for manipulating lists. For more information about lists, see Generics and Collections
(guides/librariesylibrary-tourtcollections)
Maps
In general, a map s an object that associates keys and values, Both keys and values can be any type of object. Each key occurs only
‘once, but you can use the same value multiple times. Dart support for maps is provided by map literals and the Map" type.
Here are a couple of simple Dart maps, created using map literals:
var gifts = ¢
W keys values
“finst! : "partridge’,
second": “turtledoves’,
fifth’ : ‘golden rings
h
var nobleGases
V/ Keys Values
2: ‘heliue’,
38: ‘neon’,
38: ‘argon’,
%
Note: f you're wondering whether these map literals are strong mode compliant (/guides/languageysound-dart), they are.
“Thanks to type inference /guides/language/sound-dartétype-inference), the analyzer infers that gifts, for example, has the type
MapeString, String>. Ifyou try to add non-string objects to this map under strong mode, the analyzer raises an error.
You can cteate the same objects using a Map constructorvar gifts = new ap();
gifts[‘First'] = ‘partridge’;
Bifts[ second] = ‘turtledoves"
gifts[‘Fifth’] = “golden rings
var noblecases = new Map();
nobleGases{2] = *heliun’;
nobleGases[18] = ‘neon;
nobleGases[18] = ‘argon’;
‘Add a new key-value pair to an existing map just as you would in JavaScript:
var gifts = (first': partridge’);
gifts['fourth"] = ‘calling birds’; // Add a key-value pair
Retrieve a value from a map the same way you would in JavaScript
var gift
(Cfirst!: ‘partridge’ }s
assert(gifts| first") == ‘partridge');
you look fora key that isn't in a map, you get a null in retue:
var gifts = (*Finst': ‘partrédge’)s
assert(gifts[ "fifth'] =» null);
Use . Length to get the number of key-value pairs in the map:var gifts = (*first': ‘partrédge’);
gifts[‘fourth*] = ‘calling birds";
assert(gifts. length == 2);
To create a map that’s a compile-time constant, add const before the map literal:
final constantiap = const {
2: ‘heliun’,
28: ‘neon’,
18: ‘argon’,
%
U/ constontMap[2} = ‘Helium’; // Unconmenting this causes an error.
For more information about maps, see Generics and Maps (/uides/libraries/lbrary-tourtmaps).
Runes
In Dart, runes are the UTF-32 code points ofa string,
Unicode defines a unique numeric value for each letter, digit, and symbol used in all ofthe world’s writing systems, Because a Dart
stringis a sequence of UTF-16 code units, expressing 22-bit Unicode values within a string requires special syntax
The usual way to express a Unicode code pointis \u0x, where 00K isa 4-digt hexidecimal value. For example, the heart character (¥)
's\u2665. To specify more or less than 4 hex digits, place the value in curly brackets. For example, the laughing emoji ("is \u(1#60@).
The String class has several properties you can use to extract rune information. The codeUnitat and codeUnit properties return 16.
bit code units. Use the runes property to get the runes of astring.
The following example illustrates the relationship between runes, 16-bit code units, and 32-bit code points. Click the run button (3)
tose runes inaction.Note: Be careful when manipulating runes using list operations. This approach can easily break down, depending on the
particular language, character set, and operation. For more information, see How do | reverse a String in Dart? on Stack.
Overflow.
symbols
‘A Symbol object represents an operator or identifier deciared in a Dart program. You might never need to use symbols, but they're
invaluable for APIs that refer to identifiers by name, because minification changes identifier names but not identifier symbols.
To get the symbol for an identifier, use a symbol tral, whichis just # fellowed by the identifier
radix
oar
‘Symbol literals are compile-time constants
For more information on symbols, see dartsmirrors- reflection /guides/ibraries/library-tour#éartmitroFunctions
Dartisa true object-oriented language, so even functions are objects and have a type, Function. This means that functions can be
assigned to variables or passed as arguments to other functions. You can also call an instance ofa Dart cass aif it were a function. For
details, see Callable classes.
Here's an example of implementing 2 function:
bool isNoble(int atomictunber) {
return _nobleGases[atomicNunber]
y
Although Effective Dart recommends type annotations for public APIs (/guides/language/effective-dart/design#do-type-annotate
publi-apis), the function still works lf you omit the types:
AsNoble(atonicnumber) {
return _nobleGases[atomicNunber] I= null;
y
For functions that contain ust one expression, you can use a shorthand syntax:
bool isNoble(int atomictunber)
_pobleGases[atomicNunber] != null;
The=> expr syntaxis shorthand for { return expr; }.The-=> notation is sometimes referred to as fat arrow syntax.
Note: Only an expression-not a statement-can appear between the arrow (->) and the semicolon (;), For example, you can’t put
anif statement there, but you can use a conditional expression.{function can have two types of parameters: required and optional. The required parameters are listed first, followed by any optional
parameters
Optional parameters
Optional parameters can be either positional or named, but not both
Optional named parameters
‘When calling a function, you can specify named parameters using paramWame: value. For example:
enableFlags(bold: true, hidden: false);
When defining a function, use (paran2, paran2, .) to specify named parameters:
//1 Sets the [bold] and [hidden] flags to the values
U/1 you specify.
enableFlags({bool bold, bool hidden}) {
uw
y
Optional positional parameters
Wrappinga set of function parameters in] marks them as optional positional parametersString say(String fron, String msg, [String device]) {
var result = "$from says $msg’;
if (device != null) {
result = "$result with a $device';
return result;
y
Here's an example of calling ths function without the optional parameter:
assert(say('Bob’, ‘Houdy’) == "Bod says Howdy");
{and here's an example of calling ths function with the thd parameter:
assert(say('Bob', ‘Howdy’, "stoke signal") ==
"Bob says Howdy with a smoke signal’);
Default parameter values
‘Your function can use =to define default values fr both named and positional parameters. The default values must be compile-time
constants. fno default value's provided, the default value is null.
Here's an example of setting default values for named parameters:aamaos? Language Te [Ome
U11 Sets the [bold] ond [hidden] flags to the values you
U1 specify, defaulting to false.
void enableFlags((bool bold = false, bool hidden = false)) (
uw
y
// bold will be true; hidden will be false.
enableFlags(bold: true);
Version note: Old code might use a colon (:) instead of
set default values of named parameters. The reason is that before
SOK 1.21, only : was supported for named parameters. That supports likely to be deprecated, so we recommend that you use =
to specify default values, and specify an SDK version of 1.21 or higher. (/tools/pub/pubspectsdk-constraints)
‘The next example shows how to set default values for positional parameters:
String say(String fron, String msg,
[String device = ‘carrier pigeon’, String nood]) {
var result = "$from says $msg’;
4f (device != null) ¢
result = “$result with 2 $device';
Af (mood I= null) {
result = "$result (in a $s0od mood)";
return results
»
assert(say('Bob", "Houdy")
Bob says Howdy with a carrier pigeon");You can also pass lists or maps as default values. The following example defines a function, dostu¢), that specifies a default list for
the List parameter and a default map for he gifts parameter,
void dosturf(
{Listcints List = const (1, 2, 3),
MapcString, String> gifts = const {
First’: "paper’,
second’: “cotton’,
“ehind": "Leather"
») ¢
print(‘List: $list’);
print(‘gifts: Sgifts');
y
The main() function
Every app must have a top-level nain() function, which serves as the entrypoint tothe app. The main() function returns void and has
‘an optional List parameter for arguments.
Here's an example of the nain() function for a web app:
void main() (
querySelector(“#sample_text_id")
‘ext = “Click me!
onClick. Listen(reverseText) ;
Note: The ... syntax in the preceding code is called a cascade. With cascades, you can perform multiple operations on the
members ofa single object.Here's an example of the main() function for a command-line app that takes arguments:
// Run the app Like this: dart [Link] 1 test
void main(Listestring> argusents) {
print(argunents);
assert([Link] == 2);
assert(int. parse(argunents[2])
assert(argunents[1] == ‘test');
You can use the args library” to define and parse command-line arguments
Functions as first-class objects
You can passa function asa parameter to another function. For example
printéLenent(elenent) {
print(elenent);
y
var list = [1, 2, 3];
// Pass printéLenent os @ parameter.
[Link](printElenent);
You can also assign a function to a variable, such as:
var loudify = (esg) => ‘111 ${[Link]()} 111";
assert(loudify(‘hello") =="!!! HELLO 111");This example uses an anonymous function. More about those n the next section.
Anonymous functions
Most functions are named, such as main() or printElenent(). You can also create a nameless function called an anonymous function,
for sometimes a lambda or closure. You might assign an anonymous function to a variable so that, for example, you can add or remove it
from a collection,
{An anonymous function looks similar to a named function— zero or more parameters, separated by commas and optionally typed,
between parentheses
Dart 2.0 note: Types won't be optional in Dart 2.0, but you'l still be able to omit some type annotations, thanks to type inference,
For more information, see Dart 2.0 Updates, /dart-.0)
‘The code block that follows contains the function's body:
(CUype} param, 10) ¢
codestock;
h
The following example defines an anonymous function with an untyped parameter, The function, invoked foreach item in the list,
printsa string that includes the value at the specified index
var list = [‘apples', ‘oranges*, ‘grapes’, “bananas’, ‘pluns’];
List foreach(() (
print([Link](i).tostring() +": * + 4)
ys
Clik then buton (ft execute the code.Ifthe function contains only one statement, you can shorten it using ft arrow notation. Paste the following line into DartPad and click
run to verify that itis functionally equivalent.
List. foreach((4)
print (List-indexOf(1).tostring() +": ‘ + 4))5
Lexical scope
Dart sa lexically scoped language, which means that the scope of variables is determined statically, simply by the layout of the code,
You can “follow the curly braces outwards" to see fa variable isin scope,
Here is an example of nested functions with variables at each scope levelvar toplevel = true;
rain() {
var insideMain
nyFunction() {
var insideFunction = true;
nestedFunction() {
var insideNestedFunction = true;
assert(toplevel);
assert(insidetain) ;
assert(insideFunction) ;
assert(insideNestedFunction);
Notice how nestedFunction() can use variables from every level, all the way upto the top level.
Lexical closures
{A closureis a function object that has access to variables ints lexical scope, even when the function is used outside ofits original scope.
Functions can close over variables defined in surrounding scopes. Inthe following example, sakeadder() captures the variable addy.
Wherever the returned function goes, it remembers addy.aamaos? Language Te [Ome
U1 Returns a function that adds [add8y] to the
V1) function's argument.
Function nakeAdder(num acdBy) {
return (num i) => addBy + i5
y
ain() ¢
U/ Create a function that adds 2.
var add2 = makeadder(2);
U1 Create a function that adds 4.
var adda = makeadder(4);
assert(add2(3) =
assert(adda(3)
3
ns
Testing functions for equality
Here's an example of testing top-level functions, static methods, and instance methods for equality:foot) (2 // A top-Level. function
class A {
static void bar() {} // A static method
void baz() (} // An instance method
y
ain() ¢
// Comparing top-tevel functions.
1 Comparing static methods
x = [Link];
assert([Link] == x);
U1 Comparing instance methods
new A(); // Instance #1 of A
new A()3 // Instance #2 of A
var y = 5
x= wbaz3
U1 These closures refer to the same instance (#2),
// 30 they're equal.
assert([Link] == x);
// These closures refer to different instances,
U1 so they're unequal
assert([Link] != w.b3z);Return values
Allfunctions return a value. fno return value is specified, the statement return nul; is implicitly appended to the function body.
Operators
Dart defines the operators shown in the following table. You can override many of these operators, as described in Overridable
operators.
Description
unary postfix
unary prefix
multiplicative
additive
shite
bitwise AND
bitwise xOR
bitwise OR
relational and type test
equality
logical AND
logical oR
Operator
expres expr-- (0 (] . 2.
sexpr expr ~expr expr ~-0
Sy eel
@Operator
»
conditional expr ? expr: expr3
cascade
assignment see kee oe be Me |e 28
When you use operators, you create expressions. Here are some examples of operator expressions:
arore
aist
In the operator table, each operator has higher precedence than the operators inthe rows that follow it. For example, the multiplicative
‘operator x has higher precedence than (and thus executes before) the equality operator =, which has higher precedence than the
logical AND operator &&, That precedence means that the following two lines of code execute the same way:
U1 2: Parens improve readabiLity.
AF ((o % £ == @) AB (6% i == @))
// 2: Harder to read, but equivalent.
if (ni == @ a8 d Bi == 0)
Warning: For operators that work on two operands, the leftmost operand determines which version of the operatoris used. For
‘example, ifyou have a Vector object and a Point object, Vector + aPoint uses the Vector version of +Arithmetic operators
Dart supports the usual arithmetic operators, as shown in the following table,
Operator Meaning
* Add
- subtract
“oor Unary minus also known as negation (reverse the sign ofthe expression)
: Multiply
/ Divide
~ Divide, returning an integer result
x Get the remainder ofan integer division (rodulo)
example
assert(2
assert(2
assert(2
assert(5
assert(5
assert(5 % 2
// Result is a double
// Result is an integer
// Remainder
print('s/2 = $(5~/2) © ${582}")5 // 5/2 = 201
Dart also supports both prefix and postfix increment and decrement operatorsOperator Meaning
svar vor = vor + 1 (expression valueis var + 3)
vores var = var + 1 (expression valueis var)
var var = var ~ 1 (expression valueis var ~ 3)
- var = var ~ 2 (expression valueis var)
Example
var a, bi
a= 6;
b= Has // Increment a before b gets its value.
assert(a == b); //1==1
Hs // Increment @ AFTER b gets its value.
assert(a I= b); // 1 I= 8
be // Decrement before b gets its value.
assert(a ss b); // to» -1
// Decrement a AFTER b gets its value.
assert(a I= b); //-1 l=
Equality and relational operatorsThe following table lists the meanings of equality ané relational operators
Operator Meaning
Equal; see discussion below
Not equal
> Greaterthan
< Lessthan
> Greaterthan or equal to
< Less than or equalto
To test whether two objects x and y represent the same thing, use the == operator Inthe rare case where you need to know whether
two objects are the exact same object, use the ident ical ()” function instead.) Here's how the =» operator works:
Lifer yis ull, return true if both are null, and false if only one is null
er first
2 Return the result ofthe method invocation x.==(y). (That's right, operators such as == are methods that are invoked on
‘operand, You can even override many operators, including ==, as you'l see in Overridable operators}
Here's an example of using each of the equality and relational operators:
assert(2 == 2)
assert(2 I= 3)
assert(3 > 2);
assert(2 <3);
assert(3
assert(2ecco Larne Tae Oa
Type test operators
The as, is, and is! operators are handy for checking types at runtime.
Operator Meaning
as Typecast
is ‘True ifthe object has the specified type
is! False ifthe object has the specified type
The result ofobj is Tis trueif ob; implements the interface specified by 7. For example, obj is Object is always true.
Use the as operator to cast an object to a particular type. In general, you should use it as a shorthand for an is test on an object
following by an expression using that object. For example, consider the following code;
Af (emp is Person) { // Type check
[Link] = '30b';
d
You can make the code shorter using the as operator:
(enp as Person).firstNane = "Bob's
Note: The code isn’t equivalent. if exp is null ornota Person, the frst example (with is) does nothing; the second (with as) throws
an exception
Assignment operatorsaamaos? Language Te [Ome
As you've already seen, you can assign values using the = operator. To assign only ifthe assigned-to variable is null, use the 2?=
operator.
jalue; // Assign value to a
alue; // If b is null, assign value to b;
// otherwise, b stays the sane
‘Compound assignment operators such as += combine an operation with an assignment.
Here's how compound assignment operators work:
Compound assignment Equivalent expression
Foran operator op: a op= > a= aop0
Example: aa anasd
The following example uses assignment and compound assignment operators:
var a // Assign using =
ans // Assign and multiply: a
assert(a == 6);
Logical operators
You can invert or combine boolean expressions using the logical operators.Operator Meaning
expr inverts the following expression (changes false to true, and vice versa)
uN logical oR
ry logical AND
Here's an example of using the logical operators:
AF (Idone 8& (col
U1 +0 something.
y
0 II col == 3) ¢
Bitwise and shift operators
You can manipulate the individual bits of numbers in Dart Usually, you'd use these bitwise and shift operators with integer.
Operator Meaning
& AND
H or
* XOR
expr nary bitwise complement (0s become 1s; 1s become 0s)
« Shift eft
» Shift rightHere's an example of using bitwise and shift operators:
final value = 0x22;
final bitnask = exof;
assert((value & bitnask)
assert((value & ~bitmask)
assert((value | bitnask)
assert((value * bitmask)
assert((value << 4)
assert((value >> 4)
7
x28); // AND NOT
ex2F)s // OR
ex2d); // XoR
U1 Shift Left
exe2); // Shift right
Conditional expressions
Dart has two operators that let you concisely evaluate expressions that might otherwise require if-else statements:
condition ? exprt : expr2
IF condition’s true, evaluates expr (and returns its value}; otherwise, evaluates and returns the value of expr2.
expr 22 expr2
If expr1is non-null, returns its value; otherwise, evaluates and returns the value of expr2,
When you need to assign a value based on a boolean expression, consider using ?
var finalstatus = m-isinal ? ‘final’ ; ‘not final’;
Ifthe boolean expression tests for null, consider using ??.
String toString() => msg 2? [Link]();
The previous example could have been written at least two other ways, but not as succinctly:U1 Slightly Longer version uses ?: operator.
String toString() => msg == null ? [Link]() : msgs
// Very Long version uses if-else statement.
String tostring() {
4 (msg == mull) {
return [Link]();
p else {
return nse;
Cascade notation (..)
Cascades (..) 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 This often saves you the step of creating a temporary variable and allows you to write more fluid code.
Consider the following code:
queryselector("#button') // Get an object.
sstext = ‘Confirm’ // Use its menbers.
= -[Link](" important!)
ssonCLick.1isten((e) => window-alert(*Confirmed!*));
The first method call, querySelector(), returns a selector object. The code that follows the cascade notation operates on this selector
‘object, ignoring any subsequent values that might be returned
The previous examples equivalent to:var button = querySelector( #button');
[Link] = "Confirm;
[Link](" important");
[Link]-1isten((e) => [Link](*Confirmed!"));
You can also nest your cascades. For example:
inal addressBook = (new AddresstookBuilder()
name = ‘jenny’
fenail = ‘jenny@[Link]'
phone = (new PhoneNunberBuilder()
nunber = ‘415-555-0108
«label = ‘hone")
-build())
build);
Be careful to construct your cascade on a function that returns an actual object. For example, the following code fails
U1 Does not work
var sb = new Stringouffer();
[Link]('foo"). .write(‘bar')
The [Link]() cll eturns void, and you can’t construct a cascade on vot
Note: Strictly speaking, the “double dot” notation for cascades isnot an operator. it's just part ofthe Dart syntax
Other operators
You've seen most ofthe remaining operators in other examples:Operator Name
For more information about the .,
Function
application
List access
Member access
Conditional
member access
Represents a function call
Refers to the value at the specified indexin thelist
Refers toa property of an expression; example: Foo. bar selects property bar from expression foo
Like ., but the leftmost operand can be nul; example: Foo? .bar selects property bar from expression
oo unless foo s null (in which case the value of foo? bar is null),
nd. . operators, see Classes.
Control flow statements
You can control the flow of your Dart code using any of the following
You can also affect the control flow using tr
Afandelse
for loops
whtle and do-white loops
break and continue
switch and case
Ifand else
‘catch and throu, as explained in Exceptions.
Dart supports i¢ statements with optional ese statements, as the next sample shows, Also see conditional expressions.Sf (AsRainingQ)) (
you. bringRaincoat();
} else if (isSnowing()) ¢
you,meardacket();
p else {
car. putTopbown();
y
Remember, unlike JavaScript, Dart treats all values other than true 2s false, See Booleans for more information.
For loops
You can iterate with the standard for loop, For example:
var message = new StringBuffer("Dart is fun");
for (var i= @; i < 55 ist) (
[Link]('!");
y
Closures inside of Dar’ For loops capture the value ofthe index, avoiding a common pitfall found in JavaScript, For example, consider:
var callbacks = [J;
for (var i» 8 i < 25 ise) (
[Link](() => print(i));
y
callbacks. forEach((c) => €())5
The outputs @ and then 3, as expected. In contrast, the example would print 2 and then 2in JavaScript.
Ifthe object that you are iterating over is an Iterable, you can use the Fortach() method, Using forEach() isa good option if you
don’tneed to know the cureent iteration counter:candidates. fortach( (candidate) => candidate. interview());
Iterable classes such as List and Set also support the fer-in form of iteration (/guides/librarieslibrary-tourtiteration}:
var collection = (@, 1, 2]5
for (var x in collection) {
print(x)s
y
While and do-while
[Awhile loop evaluates the condition before the loop:
while (1isbone()) {
dosonething();
y
‘[Link] loop evaluates the condition afterthe loop:
do {
printLine()3
} while (IatendofPage())s
Break and continue
Use break to stop looping:while (true) (
4f (shutDownRequested()) break;
processinconingRequests();
y
Use conti
ue to skip to the next loop iteration:
for (int 1 = @} 4 < candidates.1
var candidate = candigates[i];
AF ([Link] < 5) ¢
continue;
maths Ast) {
candidate. interview();
‘You might write that example differently if you're using an iterable
candidates where((c) => [Link] >= 5)
-forEach((c) => ¢-interview());
‘Switch and case
‘Switch statements in Dart compare integer, string, or compile-time constants using.
such as alist or set
“The compared objects must all be instances of
the same class (and not of any ofits subtypes), and the class must not override ~~. Enumerated types work wellin switch statements.
Note: Switch statements in Dart are intended for limited circumstances, such asin interpreters or scanners.Each non-empty case clause ends with a break staternent, asa rule. Other valid ways to end a non-empty case clause are a continue,
throw, or return statement,
Use adefault clause to execute code when no case clause matches:
var conmand = "OPEN";
switeh (connand) {
case ‘CLOSED":
executeClosed();
break;
case ‘PENDING’
executePending();
break;
case ‘APPROVED" :
executeApproved()
break;
case "DENIED"
executeDenied();
break;
case ‘OPEN
executeopen();
break;
default:
‘executeUnknown()
The following example omits the break statement in case clause, thus generating an error:var command = “OPEN' 3
switch (connand) {
case ‘OPEN
‘executeopen();
// ERROR: Missing break causes an exception! !
case *CLOSED"
executeClosed();
break;
However, Dart does support empty case clauses, allowing a form of fallthrough:
var conmand = “CLOSED
switch (command) {
case ‘CLOSED: // Empty case falls through
ease "NOH_CLOSED"
U1 Runs for both CLOSED and NOw_CLOSED.
executeliovClosed();
break;
you really want fall-through, you can use a continue statement and a label:aamaos? Language Te [Ome
var conmand = “CLOSED';
switch (command) {
case ‘CLOSED"
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed Label.
nowclosed
cease ‘NOM_ CLOSED
// Runs for both CLOSED and NOw_CLOSED.
‘executehiowClosed();
break;
‘case clause can have local variables, which are visible only inside the scope ofthat clause.
Assert
Use an assert statement to disrupt normal execution ifa boolean condition is false, You can find examples of assert statements
throughout this tour. Here are some more:
// Make sure the variable has a non-null value,
assert(text I= null);
// Moke sure the value ts Less than 160.
assert(nunber < 120);
// Make sure this is on https URL.
assert([Link](https"));
Note: Assert statements work only in checked mode. They have no effect in production mode.Dart 2.0 note: Checked mode won't be in Dart 2.0, For more information, see Dart 2.0 Updates. (/dart-2.0)
To attach a message toan assert, adda string as the second argument.
assert([Link]( https"),
URL (SuriString) should start with "https”.");
Version note: The second argument was introduced in SDK 1.22,
The first argument to assert can be any expression that resolves to a boolean value or to a function. Ifthe expression’s value or
function's return value is true, the assertion succeeds and execution continues. Ifit's false,
[Link])is thrown.
the assertion fils and an exception (an
Exceptions
Your Dart cade can throw and catch exceptions. Exceptions are errors indicating that something unexpected happened. Ifthe exception
isnt caught, the isolate that raisee the exception is suspended, and typically the isolate and its program are terminated
In contrast to Ja
all of Dart’ exceptions are unchecked exceptions, Methods do not declare which exceptions they might throw, and
you are not required to catch any exceptions.
Dart provides Exception ® and Error“ types, as well as numerous predefined subtypes. You can, of course, define your own exceptions.
However, Dart programs can throw any non-null object—not just Exception and Error objects—as an exception,
Throw
Here's an example of throwing, or raising, an exception:‘throw new FormatException( ‘Expected at least 1 section);
You can also throw arbitrary objects:
‘throw ‘Out of Manasl';
Because throwing an exception is an expression, you can throw exceptions in ~> statements, as well as anywhere else that allows
expressions:
AistanceTo(Point other) =>
‘throw new UninplenentedError();
Catch
Catching, or capturing, an exception stops the exception from propagating (unless you rethrow the exception}. Catching an exception
gives you a chance to handleit:
try (
breedMoreLlanas();
} on outofLianaséxception {
buyMoreLanas()
y
Tohhandle code that can throw more than one type of exception, you can specify multiple catch clauses, Te frst catch clause that
matches the thrown objects type handles the exception, Ifthe catch clause does not specify a type, that clause can handle any type of
thrown abject:try (
breedMorel lanas();
} on OutofLianaséxception {
U1 A specific exception
buyMoret lanas();
‘on Exception catch (e) ¢
U1 Anything else thot ts an exception
print (‘Unknown exception: $e");
) catch (e)
// No specified type, handles all
print('Sonething really unknown: $e");
As the preceding code shows, you can use either on or catch or both. Use on when you need to specify the exception type, Use catch
when your exception handler needs the exception object.
You can specify one or two parameters to catch(). The firsts the exception that was thrown, and the second isthe stack trace (a
StackTrace” object
} on Exception catch (e) ¢
print(‘Exception details:\n $e");
} catch (e, 5) (
print(‘Exception details:\n $e");
print(‘Stack trace:\n $s");
>
To partially handle an exception, while allowing it to propagate, use the rethrow keyword,aamaos? Language Te [Ome
final foo =
void misbehave() (
try {
foo = “You can't change @ final variable’s value.";,
} catch (©) {
print(‘misbehave() partially handled ${[Link]}
rethrow; // Allow callers to see the exception.
y
void main() (
try ¢
rnisbehave();
} eaten (0)
print(’nain() finished handling ${[Link])
Finally
To ensure that some code runs whether or not an exception is thrown, use a finally clause. Ifno catch clause matches the exception,
the exception is propagated after the finally clause runs:
try (
breedvoreLlanas();
} Finally {
U1 Always clean up, even if an exception ts thrown.
cleantlanastalls()3
yThe finally clause runs after any matching catch clauses:
try
breedMoreLanas();
} eateh(e) ¢
print(‘Error: $e"); // HandLe the exception first.
} finally {
cleanLlanastalis(); // Then clean up.
y
Learn more by reading the Exceptions /guides/libraries/library-tourtexceptions) section,
Classes
Dart is an object-oriented language with classes and mixin-based inheritance. Every object is an instance ofa class, and all classes
descend from Object. Mixin-based inheritance means that although every class (except for Object) has exactly one superclass class
body can be reused in multiple class hierarchies,
To create an object, ou can use the new keyword with a constructorfor a class. Constructor names can be either CLassName or
CLassNome. identifier. For example:
var jsonData = [Link]("("x":1,
U1 Create a Point using Point()
var pi = new Point(2, 2);
// Create @ Point using [Link]().
var p2 = new [Link])son(jsondata);
Objects have members consisting of functions and data (methods and instance variables, respectively), When you calla method, you
invokeit on an object: the method has access to that object's functions and date,Use adot(.) to refer to an instance variable or method
var p = new Point(2, 2);
U1 Set the value of the instance variable y.
py
// Get the value of y.
assert(p.y == 3);
// Invoke distanceTo() on p.
num distance = [Link](new Point(4, 4));
Use 2. instead of . to avoid an exception when the leftmost operands null:
UL Tf p AS non-null, set its y value to 4.
pry = 45
‘Some classes provide constant constructors To create 2 compile-time constant using a constant constructor, use const instead of new:
var p = const InmutablePoint(2, 2)3
Constructing two identical compile-time constants results in a single, canonical instance:
var a = const InmutablePoint(1, 1);
var b = const InqutablePoint(1, 1);
assert(identical(a, b)); // They are the same instance!
To get an objects type at runtime, you can use Object’s runtineType property, which returns a Type“
object.print("The type of a is $([Link]}");
The following sections discuss how to implement classes.
Instance variables
Here's how you declare instance variables:
class Point (
nun x; // Declare instance variable x, initially null.
num y3 // Declare y, initially mult
num 2 = @; // Declare z, initially 8.
All uninitialized instance variables have the value nul
Allinstance variables generate an implicit gettermethod. Non-final instance variables also generate an implicit setter method. For
details, see Getters and setters
class Point (
num ys
y
eain() ¢
var point = new Point();
point.x = 43 // Use the setter method for x.
assert(point .x
assert(point.y
y
4); // Use the getter method for x
= null); // Values default to nutIt you initialize an instance variable where itis declared (instead of ina constructor or method), the value Is set when the instanceis
created, wich is before the constructor and its initializer list execute,
Constructors
Declare a constructor by creating 2 function with the same name as its class (plus, optionally, an additional identifier as described in
Named constructors). The most common form of constructor, the generative constructor, creates a new Instance of a class:
class Point (
num y3
Point(num x, num y) {
// There's a better way to do this, stay tuned.
this.x
The this keyword refers to the current instance.
Note: Use this only when there is a name conflict, Otherwise, Dat style omits the this,
‘The pattern of assigning a constructor argument to an instance variable is so common, Dart has syntactic sugar to make it easy:class Point (
num y;
// Syntactic sugar for setting x and y
U1 before the constructor body runs.
Point(this.x, this.y);
y
Default constructors
Ifyou don’t declare a constructor, a default constructor is provided for you. The default constructor has no arguments and invokes the
no-argument constructor in the superclas,
Constructors aren't inherited
‘Subclasses don't inherit constructors from their superclass. A subclass that declares no constructors has only the default (no argument,
noname} constructor.
Named constructors
Use a named constructor to implement multiple constructors fora class orto provide extra clarity:class Point (
num y;
Point(this.x, this.y);
// Named constructor
Point. fron3son(Wap json) (
x= Json['x'];
y = json['y']s
Remember that constructors are not inherited, which means that a superclass’s named constructor isnot inherited by a subclass. Ifyou
want a subclass to be created with a named constructor defined inthe superclass, you must implement that constructor in the
subclass
Invoking a non-default superclass constructor
By default, a constructor in a subclass calls the superclass’ unnamed, no-argument constructor, The supeclas's constructors called
atthe beginning ofthe constructor body. fan inialize lists also being used, it executes before the superclass called, In summary,
the order of executions as follows
1 initilzer ist
2. supercass's no-arg constructor
2 main class's no-arg constructor
ifthe superlass doesn'thave an unnamed, no-argument constructor, then you must manually cal one ofthe constructrsin the
‘superclass. Specify the superclass constructor after a colon (:), just before the constructor body (if any).
Inthe folowing example, the constructor fr the Employee class calls the named constructor frit superclass, Person, lick the run
button (FS) to execute the codeBecause the arguments tothe superclass constructor are evaluated before invoking the constructor, an argument can be an expression
such as a function cal
class Employee extends Person (
Employee() : super. frondson( Findbefaultoata())
>Note: When using super() in a constructor’ initialization lis, putt last. or more information, see the Dart usage guide
(iguides/language/effective-dart/usagetdo-place-the-super-cal-last-in-a-constructor-initialzationist).
Warning: Arguments to the superclass constructor do not have access to this, For example, arguments can call static methods
but notinstance methods.
Initializer list
Besides invoking a superclass constructor, you can also initialize instance variables before the constructor body runs. Separate
iniializers with commas.
class Point (
num y3
Point(this.x, this.y);
// Initialize List sets instance variables before
// the constructor body runs:
Point .fronson(Map sorMap)
jsontapl x"),
y = Jsonmap('y") {
print("In [Link](): ($x, $¥)")s
y
hand side ofan initializer does not have access to this,
Warning: The righaamaos? Language Te [Ome
Iniializer ists are handy when setting up final felds. The following example initializes three final elds in an initializer list. Click the run
button (J) to execute the code.
Redirecting constructors
Sometimes a constructors only purpose sto redirect to another constructor inthe same clas. A redirecting constructor’ body is
empty, with the constructor call appearing ater a colon ()aamaos? Language Te [Ome
class Point (
num y;
// The main constructor for this class.
Point(this.x, this.y);
U/ delegates to the main constructor.
Point alongxAxts(num x) : this(x, 8);
Constant constructors
your class produces objects that never change, you can make these objects compile-time constants. To do this, define a const
constructor and make sure that all instance vatlables are Final,
class InnutablePoint {
‘final num x;
‘final nun y:
const InnutablePoint(this.x, this.y);
static final InnutablePoint origin =
‘const InmutablePoint (2, 2);
Factory constructors
Use the Factory keyword when implementing a constructor that doesnt always create a new instance ofits class. For example,
factory constructor might return an instance from a cache, o it might return an instance ofa subtype
‘The following example demonstrates a factory constructor returning objects from a cache:aamaos? Language Te [Ome
class Logger (
final String name;
bool mite = false;
// cache is Librory-private, thanks to the _ in front
U1 of its name
static final map _cache =
(};
factory Logger(String rane) (
4f (cache. containskey(nare)) {
return _cache( name);
} else ¢
Final logger = new Logger._internal (nave);
_cache[nare] = logger;
Feturn logger;
»
Logger._internal([Link]);
void log(string msg) {
af (Imute) {
print (ase);
y
Note: Factory constructors have no access to this,
Toinvoke a factory constructor, you use the new keyword:var logger = new Logger( UI");
Logger. 1og( ‘Button clicked");
Methods
Methods are functions that provide behavior for an object.
Instance methods
Instance methods on objects can access instance variables and this, The dist:
of an instance method:
1ceT@() method in the following sample is an example
import ‘dart:nath’;
class Point
num y3
Point(this.x, this.y);
num distanceTo(Point other) (
var dx = x - other.x;
var dy = y - [Link]
return sqrt(dx * ax + dy * dy);
Getters and setters
Getters and setters are special methods that provide read and write access to an object's properties. Recall that each instance variable
has an implicit getter, plus a setter if appropriate, You can create additional properties by implementing getters and setters, using the
get and set keywords:class Rectangle (
nun left;
num top;
num widths
num heights
Rectangle(this. left, [Link], [Link], [Link]);
// define two calculated properties: right and bottom.
num get right => left + width;
set right(num value) => left = value ~ widths
num get botto= top + heights
set botton(num value) => top = value - heights
y
rain() ¢
var rect = new Rectangle(3, 4, 20, 15);
assert([Link] == 3);
[Link] = 12;
assert([Link] == -8);
>
With getters and setters, you can start with instance variables, later wrapping them with methods, all without changing client code,
Note: Operators such as increment (++) work in the expected way, whether or not a getter is explicitly defined, To avoid any
unexpected side effects, the operator cals the getter exactly once, savingits value ina temporary variable.
Abstract methods
Instance, getter, and setter methods can be abstract, defining an interface but leaving its implementation up to other classes. To makea
method abstract, use a semicolon (}) instead of a method body:abstract class Deer {
U1 «Define instance variables and methods.
void doSonething(); // Define an abstract method.
y
class EffectiveDoer extends Doer {
void dosonething() {
U1 .-Provide an implementation, so the method is not abstract here...
Calling an abstract method results in a runtime error
Also see Abstract classes.
Overridable operators
You can override the operators shown inthe fllowing table. For example, fyou define aVectr class, you might define a + method to
add two vectors
< + a
> / . oO
® -
- x >
Here's an example of a class that overrides the + and - operators:class Vector (
final int x;
final int ys
const Vector(this.x, this.y);
UII overvides + (a +b).
Vector operator +(Vector v) {
return new Vector(x + v.x, ¥ + V.y)
U1 overrides - (a - b).
Vector operator -(Vector v) {
return new Vector(x - v.x, y - v.y)3
y
atn() ¢
final v = new Vector(2, 3);
final w = new Vector(2, 2);
Uv = (2, 3)
assert(v.x == 2 88 vy
MUvewes (4, 5)
assert((v + m).x = 4 8& (V+ wD. == 5)5
Uv owen (8, 1)
assert((v - m).x 22 8 88 (v- w)-y == 1)5
Ityou override ==, you should also override Object’s hashCode getter. For an example of overriin
map keys (/guides/libraries/ibrary-tourkimplementing-map-keys)
and hashcode, see Implementing
For more information on overriding, in general, see Extending a classAbstract classes
Use the abstract modifier to define an abstract class—a class that can't be instantiated. Abstract classes are useful fr defining
interfaces, often with some implementation. f you want your abstract class to appear to be instantiable, define a factory constructor.
Abstract classes often have abstract methods, Here's an example of declaring an abstract class that has an abstract method:
U/ This class is declared abstract ond thus
// can't be instantiated.
abstract class Abstractcontainer {
// «define constructors, fields, methods
void updatechildren(); // Abstract method.
y
The following class isn’t abstract, and thus can be instantiated even though it defines an abstract method
class Specializedcontainer extends AbstractContainer {
// ...befine more constructors, fields, methods...
void updatechildren() {
// «Implement updatechildren()...
// Abstract method causes @ warning but
U1 doesn't prevent instantiation.
void doSonething();
y
Implicit interfacesaamaos? Language Te [Ome
Every class implicitly defines an interface containing all the instance members of the class and of any interfaces it implements. Ifyou
want to create a class A that supports class B's API without inheriting B's implementation, class A should implement the B interface.
‘Aclass implements one or more interfaces by declaring them in an implements clause and then providing the APIs required by the
interfaces. For example:
// A person. The implictt interface contains greet().
class Person (
// In the interface, but visible only in this Library.
‘final _nane;
// Not in the interface, since this is @ constructor.
Person(this._nane);
// In the interface.
String greet (who) => ‘Hello, $who. I am $nane.";
d
// An implementation of the Person interface.
class Inposter inplenents Person {
// We have to define this, but we don't use it.
final _nane = ""5
String greet (who) => ‘HL $who. Do you know who T am?*;
y
greetdob(Person person) => [Link] (“bob");
rain() {
print(greetBob(new Person( kathy')));
print(greetBob(new Inposter()));
y
Here's an example of specifying that a class implements multiple interfaces:class Point inplenents Comparable, Location (
uw
y
Extending a class
Use extends to create a subclass, and super torefer to the superclass:
class Television (
void turnon() {
_Sluninatepisplay()s
Tactivaterrsensor();
uw
y
class SnartTelevision extends Television (
void turnon() {
super. turnon()
_pootNetworkinterface()s
Tinitializetenory();
Tupgradeapps() 3
uw
y
Overriding members
Subclasses can override instance methods, getters, and setters. You can use the Boveride annotation to indicate that you are
intentionally overriding a member:class SnartTelevision extends Television (
Goverride
void turnon() {
Tonarrow the type of a method parameter or instance variable in code that is type safe (/guides/language/sound-dart), you can use the
covariant keyword (/guides/language/sound-problemstthe-covariant-keyword)
noSuchMethod()
To detec or react whenever code attempts to use 8 non-existent method or instance variable, you can override nosuchMethoa()
class A {
// Unless you override noSuchMethod, using a
// non-existent member results in a NoSuchMethodérror.
void noSuchMethod(Iavocation mirror) {
print(‘You tried to use a non-existent nenber:’ +
‘$(nieror-menberNane)")
Ifyou use nosuchttethnod{) to implement every possible getter, setter, and method for one or more types, then you can use the @proxy
annotation to avoid warningsproxy
class A {
void noSuchMethod(Iavocation mirror) {
An alternative to @proxy, if you know the types at compile time, isto just declare that the class implements those types.
class A implenents SoneClass, SonetherClass (
void noSuchMethod(Iavocation mirror) {
For more information on annotations, see Metadata,
Enumerated types
Enumerated types, often called enumerations or enums, are a special king of class used to represent a fixed number of constant values.
Using enums
Declare an enumerated type using the enum keyword:
enum Color <
red,
green,
blue
yaamaos? Language Te [Ome
Each value in an enum has an index getter, which returns the 2ero-based position of the value inthe enum declaration. For example,
the first value has index 0, and the second value has index 1.
assert([Link]. index
assert([Link]
assert([Link]. index
To get alist ofall of the valuesin the enum, use the enum's values constant.
Listccoler> colors = [Link]
assert(colors[2] == [Link]);
You can use enums in switch statements. fthe ein switch (e) is explicitly typed as an enum, then you're warned if you don't handle
all ofthe enum’s values:enun color {
red,
Breen,
blue
y
Wow
Color acolor = [Link];
suiteh (acolor) {
case [Link]:
print(‘Red as roses!");
break;
case Color. green:
print(‘Green as grass!");
break;
default: // Without this, you see a WARNING.
print(aceler); // "[Link]”
Enumerated types have the following limits:
+ You car't subclass, mixin, orimplement an enum,
+ You can't explicitly instantiate an enum,
For more information, see the Dart Language Specification (/guides/language/spec).
Adding features to a class: mixins
Mins ar a way of using a cas’ codein multiple cass hierarchies
To use a mixin, use the with keyword followed by one or more mixin names. The following example shows two classes that use mixins:class Musician extends Performer with Musical (
uw
class Maestro extends Person
with Musical, Aggressive, Denented {
Maestro(String maestroNane) {
name = naestroNane;
canConduct = true;
Toimplement a mixin, create a class that extends Object, declares no constructors, and has no calls to super. For example:
abstract class Musical {
bool canPlayPiano = false;
bool canConpose = false;
bool canconduct = false;
void entertainte() {
Af (canPlayPiano) {
print ("Playing piano’);
} else iF (canconduct) {
print(*waving hands");
} else {
print (*Hurming to self")
y
Note: As of 1.13, two restrictions on mixins have been led from the Dart VM:aamaos? Language Te [Ome
+ Mixins allow extending from a class other than Object.
+ Mixins can call super()
‘These “super mixins” are not yet supported in dart2/s and require the --supermixin flag in dartanalyzer.
For more information, see the article Mins in Dart, /aticles/language/mixins)
Class variables and methods
Use the static keyword to implement class-wide variables and methods.
Static variables
Static variables (class variables) are useful forclass-wide state anc constants:
class Color (
static const red
const Color(‘red'); // A constant static variable.
final string name; // An instance variable.
const Color([Link]); // A constant constructor.
y
rain() {
assert([Link] == “red’);
y
Static variables arent initialized until they're used.
Note: This page follows the style guide recommendation /guides/language/effective-dart/stylesidentifiers) of preferring
jowerCanel Case for constant names,aamaos? Language Te [Ome
Static methods
Static methods (class methods) do not operste on an instance, and thus do not have access to this. For example:
import ‘dart:nath';
class Point (
num ys
Point(this.x, this.y);
static num distancesetween(Point a, Point »)
var dx = a.x = Bux;
var dy = ay - by;
return sqrt(dx * dx + dy * dy)s
y
ain() ¢
var a = new Point(2, 2);
var b = new Posnt(4, 4);
var distance = [Link](a, b);
assert(distance < 2.9 & distance > 2.8);
Note: Consider using top-level functions, instead of static methods, for common or widely used utilities and functionality.
You can use static methods as compile-time constants, For example, you can passa static method as a parameter toa constant
constructor.
Genericsaamaos? Language Te [Ome
Ifyou look at the API documentation for the basic array type, List,“ you'l see thatthe type is actually List. The«<..notation
marks Listas a generic (or parameterized) tyoe—a type that has formal type parameters. By convention, type variables have single-
leter names, such as, T, 5, K, and
Why use generics?
Because types are optional in Dart 1.x, you never haveto use generics. You might wantto, though, for the same reason you might want
{0 use other types in your code: types (generic or not} let you document and annotate your code, making your intent clearer.
Dart 2.0 note: Types won't be optional in Dart2.0, but you'l stil be able to omit some type annotations, thanks to type inference,
For more information, see Dart2.0 Updates. (/dart-2.0)
For example, ifyou intend fora ist to contain only strings, you can declare itas List (read thatas "lst of string"). That way
you, your fellow programmers, and your tools (such as your IDE and the Dart VM in checked mode) can detect that assigning a non-
string to the lists probably a mistake. Here's an example:
var nanes = new List();
[Link]éAl1(["Seth", ‘Kathy’, ‘Lars']);
Mon
[Link](42); // Fails in checked mode (succeeds in production mode).
Another reason for using generies isto reduce code duplication, Generics let you share a single interface and implementation between
many types, while stil taking advantage of checked mode and static analysis early warnings. For example, say you create an interface
for caching an object:
abstract class Objectcache (
Object getBykey(String key);
setsyxey(String key, Object value);
yYou discover that you want a string-specific version of this interface, so you create another interface:
abstract class Stringcache (
String getBykey(string key);
setaykey(String key, String value);
»
Later, you decide you want a number-spacific version of tis interface... You get the idea
Generic types can save you the trouble of creating al these interfaces. Instead, you can create a single interface that takes 2 type
parameter:
abstract class CachecT> {
T getBykey(String key);
sevsykey(String key, T value);
y
In this code, Tis the stand-in type. It's a placeholder that you can think of as type that a developer will define later.
Using collection literals
List and map literals can be parameterized. Parameterized literals are just lke the literals you've already seen, except that you add
(fr lists) or (for maps) before the opening bracket. You might use parameterized literals when you want
type watnings in checked mode, Heres example of using typed literals:
var names = ['Seth*, ‘Kathy’, ‘Lars'];
var pages = (
[Link]": “Honepage’,,
[Link]’: “Hints for web robots’,
[Link]": “Ke are people, not machines”
bUsing parameterized types with constructors
To specify one or more types when using a constructor, put the types in angle brackets (c..>) just after the class name. For example:
var nanes = new List();
[Link](["Seth', ‘Kathy’, ‘Lars']);
var naneSet = new Set.fron(nanes);
The following code creates a map that has integer keys and values of type View:
var views,
new Mapcint, View();
Generic collections and the types they contain
Dart generic types are reified, which means that they carry their type information around at runtime. For example, you can test the type
of collection, even in production mode:
vvar nanes = new List(
hames.addAl1(["Seth", ‘Kathy’, ‘Lars']);
print(nanes is ListString>); // true
However, the £s expression checks the type ofthe collection only—nat ofthe object
might have some non-string items init. The solution isto either check each
handler (see Exceptions).
Inside it. In production mode, a List«string>
sms type or wrap item-manipulation code in an exception
Note: in contrast, generics in Java use erasure, which means that generic type parameters are removed at runtime. In Java, you
‘can test whether an object isa Lis, but you can't test whether i's a ListeStringscans Language Ts 10m
Restricting the parameterized type
When implementing a generic type, you might want to limit the types of its parameters. You can do this using extends.
/1 1 must be SonebaseClass or one of its descendants.
class FoocT extends SonesaseClass> {...}
class Extender extends SonetaseClass {
void main() (
// It's OK to use SomeBaseClass or any of its subclasses inside <>.
var soneBaseClassfoo = new Foo();
var extenderFoo = new Foo();
// It's also OK to use no <> at atl.
var foo = new Foo();
1 Specifying any non-SomeBaseClass type results in a warning and, in
W/ checked mode, @ runtime error.
U1 var objectFoo = new Foocobject>();
Using generic methods
Initially, Dar’s generic support was limited to classes. Anewer syntax, called generic methods, allows type arguments on methods and
functions:T #irstet> (ListeT> ts) (
// «+0 some initial work or error checking, then...
T tmp = ts(@]s
U1 «+0 some additional. checking on processing.
retura tap;
Here the generic type parameter on Finst (c1>) allows you to use the type argument Tin several places:
+ In the function's return type (7)
+ Inthe type of an argument (ListeT>)
+ Inthe type ofa local variable (T tmp)
Version note: The new syntax fr generic methods was introduced in SDK 1.21, “ Ifyou use generic methods, specify an SDK
version of 1.21 or higher. /tools/pub/pubspectsck-constraints)
For more information about generics, see Using Generic Methods.
Libraries and visibility
The import and 1sbrary directives can help you create a modular and shareable code base. Libraries not only provide APIs, but area
Unit of privacy: identifies that start with an underscore (_) are visible only inside the library, Every Dart app isa library, even it doesn’t
use a Library directive
Libraries can be distributed using packages. See Pub Package and Asset Manager (toals/pub) for information about pub, a package
manager included inthe SDK.
Using libraries
Use inport to specify how a namespace from one library is used in the scope of another library.For example, Dart web apps generally use the dartihtml ibrary, which they can import ike this:
import ‘dart:hte:
The only required argument to impor‘ isa URI specifying the library. For builtin libraries, the URI has the special dart: scheme. For
other libraries, you can use a fil system path or the package: scheme. The package: scheme specifies libraries provided by a package
manager such asthe pub tool. For example:
import ‘dart:io"s
import. ‘package:mylib/nylib. dart’
import. ‘package:utils/[Link]’;
Note: UR!stands for uniform resource identifier. URLs (uniform resource locators) are a common kind of URI
Specifying a library prefix
Ifyou import two libraries that have conflicting identifiers, then you can specify a prefix for one or both libraries. For example, if library.
and ibrary2 bath have an Element las, then you might have code like this
import. ‘package:1ib1/[Link]’
import ‘package:1ib2/[Link]” as 11b2;
Wo
Elenent elenenti = new Elenent(); U1 Uses Etement from Libt.
[Link] elenent2 = new [Link](); // Uses ELement from Lib2.
Importing only part of a library
ifyou want to use only part of library, you can selectively import he library.UL Inport onty foo.
import ‘package:1ibi/[Link]’ show foo;
// Import aU names EXCEPT foo.
import. ‘package:1ib2/[Link]” hide foo;
Lazily loading a library
Deferred loading (aso called zy loading) allows an application to load a library on demand, fand when it’s needed. Here are some
cases when you might use deferred loacing
+ Toreduce an app'sinitial startup time.
+ To perform AB testing—trying out alternative implementations ofan algorithm, for example
+ Toload rarely used functionality, suchas optional screens and dialogs.
To aaily oad a library, you must fist importitusing deferred as.
import ‘package:deferred/[Link]’ deferred as hello;
When you need the library, invoke loadl brary() using the library's identifier
greet() async {
await hello. loadLibrary();
[Link]();
y
In the preceding code, the await keyword pauses execution until the library is loaded. For more information about async and await,
see asynchrony support.
You can invoke toadtibrary() multiple times ona library without problems. The library is loaded only once.
Keep in mind the following when you use deferred loading:aamaos? Language Te |O5e
+ Adeferredlibrary’s constants aren't constants in the importing file. Remember, these constants don't exist until the deferred
library is loaded
+ You can’t use types from a deferred library inthe importing file. Instead, consider moving interface types to a library imported by
both the deferred library and the importing fle
+ Dart implicitly inserts oadLibrary() into the namespace that you define using deferred as namespace. The loadt ibrary()
function returns a Future (/guidesytibraies/ibrary-tour#future),
Implementing libraries
‘See Create Library Packages {/guides/ibraries/ereate-library-packages) for advice on how to Implement a library package.
Asynchrony support
Dart has several language features to support asynchronous programming, The most commonly used of these features are async
functions and avait expressions.
Dart libraries ae full of functions that return Future or Stream objects. These functions are asynchronous: they return after setting up 2
possibly time-consuming operation (such as /0), without waiting fr that operation to complete.
When you need to use a value represented by a Future, you have two options:
+ Use async and await
+ Use the Future API (/guides/libraries/library toursfuture)
Similarly, when you need to get values from a Stream, you have two options:
+ Use asyne and an asynchronous for loop (await for)
+ Use the Stream API (/guides/ibrariesjlibrary-toursstream)
Code that uses async and await is asynchronous, but it looks a ot like synchronous code. For example, here's some code that uses
await to wait for the result of an asynchronous function:
amait LookupVersion()Touse await, code must be in a function marked as asyne:
checkversion() asyne {
var version = await lookvpVersion();
Af (version == expectedversion) {
U1 0 something.
) else ¢
// Do something etse.
You can use try, catch, and Finally to handle errors and cleanup in code that uses await:
try
server = await [Link](InternetAddress..LOOPBACK_IP_V4, 4044);
} catch (e)
// React to inability to bind to the port.
y
Declaring async functions
[An asyne function's a function whose body is marked with the asyne modifier. Although an async function might perform time-
consuming operations, it returns immediately before any ofits body executes,
checkversion() async {
uw
y
LookUpversion() async => /* ... */;aamaos? Language Te [Ome
[Adding the async keyword to a function makes it return a Future, For example, consider this synchronous function, which returns a
String:
‘String LookUpversionsyne()
Ifyou change it to be an async function—for example, because a future implementation wil be time consuming—the returned value isa
Future:
FuturecString> lookupversion() async => "1.0.0";
Note that the function's body doesn’t need to use the Future API. Dart creates the Future object if necessary.
Using await expressions with Futures
{An await expression has the following form:
anait expression
You can use await multiple times in an async function. For example, the following code waits three times forthe results of functions:
var enteypoint = await findentrypoint();
var exitcode = await runéxecutable(entrypoint, args);
await flushThenkxit(exitCode);
In await expression, the value of expressions usually a Future; ifitisa't then the value is automatically wrapped in a Future. This
Future object indicates a promise to return an object. The value of await expresston is that returned object. The await expression
makes execution pause until that object is availabe.
Iawait doesn’t work, make sure it’s in an async function. For example, to use await in your app's main() function, the body of
mmain() must be marked as asyne:pain() asyne (
checkversion()
print("In main: version is ${await lookUpversion()}");
y
Using asynchronous for loops with Streams
{An asynchronous for loop has the following form:
await for (variable declaration in expression) {
// Executes each time the strean emits 2 value.
y
The value of expression must have type Stream. Execution proceeds as follows:
1 Wait until the stream emits avalue.
2 Execute the body ofthe for loop, withthe variable set to that emitted value.
3. Repeat 1 and 2 until the stream is closed,
To stop listening tothe stream, you can use @ break or return statement, which breaks out of the for loop and unsubscribes from the
stream,
Ifan asynchronous for loop doesn’t work, make sure it's in an asyne functi
app'smain() function, the body of main() must be marked as async:
For example, touse an asynchronous for oop in yourpain() asyne (
await for (var request in requestServer) (
handleRequest (request);
For more information about asynchronous programming, see the dart:asyne (/guides/librariesjlibrary-tourtdartasyne—~asynchronous-
programming) section ofthe library tour. Also see the articles Dart Language Asynchrony Support: Phase 1 (/artcles/tanguage/awalt-
‘asyne) and Dart Language Asynchrony Support: Phase 2 (/atiles/language/beyondl-async), and the Dart language specification
Uguides/language/spec).
Callable classes
To allow your Dart class tobe called like a function, implement the ¢211() method,
In the following example, the WannabeFuncton class defines a call) function that takes three strings and concatenates them,
separating each with a space, and appending an exclamation. Click the run button 3] to execute the code
For more information on treating classes like functions, see Emulating Functions in Dart (/articles/language/emulating-functions)Isolates
Modern web browsers, even on mobile platforms, run on multi-core CPUs, To take advantage ofall those cores, developers traditionally
se shared-memory threads running concurrently, However, shared-state concurrency is errr prone and can lead to complicated code,
Instead of threads, all Dart code runs inside of isolates. ach isolate has its own memory heap, ensuring that no isolates state is
accessible from any other isolate.
Typedefs
In Dart, functions are objects, just ke strings and numbers are abject. A typedef or function-type alias, gives a function type a name
that you can use when declaring fields and retuen types. A typedef retains type information when a function type is assigned toa
variable
Consider the following code, which doesn't use a typedet:class Sortedcollection {
Function compare;
Sortedcollection(int #(object a, Object b)) {
compare = 3
// Initial, broken implementation.
int sort(object a, Object b) => a;
rain() {
Sortedcollection coll = new Sortedcollection(sort);,
U1 ALL we know is that compare is a function,
// but what type of function?
assert([Link] 4s Function);
y
‘Type information is lost when assigning F to compare. The type of Fis (Object, Object) ~» int (where —» means returns), yet the type
cof compare is Function. Ifwe change the code to use explicit names and retain type information, both developers and tools can use that
information,aamaos? Language Te [Ome
typedef int Conpare(Object a, object b);
class Sortedcollection {
Compare compare;
Sortedcollection([Link]);
y
// Initial, broken implementation.
int sort(object a, Object b) => a;
rain() {
‘Sortedcollection coll = new Sortedcollection(sort);,
assert([Link] is Function);
assert([Link] is Compare);
y
Note: Currently, typedets are restricted to function types. We expect tis to change.
Because typedefs are simply aliases, they offer a way to check the type of any function. For example:
typedef int Compare(int a, int b);
int sort(int a, int b) => a - b5
pain() {
assert(sort is Compare); // True!
yNew function type syntax: Dart 1.24 introduced a new form of function types, the generic function type alias. You might use
this Feature f you pass around generic methods, define field that are function types, or define arguments with generic function
types. Here's an example of using the new syntax:
typedef F = ListeT> Function <1>(1);
Metadata
Use metadata to give additional information about your code. A metadata annotation begins with the character 8, fllowed by either a
reference toa compile-time constant (such as deprecated) or acallto a constant constructor.
Three annotations are available toa Dart code: deprecated, override, and Goroxy. For examples of using override and Goroxy,
see Extending a class. Here's an example of using the @éeprecated annotation
class Television (
U1 Deprecated: Use [turndn} instead._
deprecated
void activate() {
rnon();
U1 Turns the TV's power on
void turnon() {
print(‘on!");
You can define your own metadata annotations. Here's an example of defining a @todo annotation that takes two arguments:aamaos? Language Te [Ome
Library todo;
class todo (
Final String who;
final String whats
const todo([Link], this-what);
y
‘And here's an example of using that
import. ‘todo. dart” 5
Gtodo('seth’, ‘rake this do sorething')
void dosonething() {
print(‘do something");
y
Metadata can appear before a library, class, typedet, type parameter, constructor, factory, function, field, parameter, or variable
declaration and before an import or export directive. You can retrieve metadata at runtime using reflection.
Comments
Dart supports single-line comments, multi-line comments, and documentation comments.
Single-line comments
Asingle-line comment begins with //. Everything between // and the end of line is ignored by the Dart compiler.ratn() {
// 1000: refactor into an AbstractLLomaGreetingFactory?
print(‘Welcome to my Lana farm!');
y
Multi-line comments.
Amultitine comment begins with /* and ends with */. Everything between /* and */ is ignored by the Dart compiler (unless the
comments a documentation comment; see the next section). Multiline comments can nest
pain() ¢
”
+ This is a Lot of work. Consider raising chickens.
lana Larry = new Ltana();
lorry. feed();
[Link]();
Larry. clean();
”
Documentation comments
Documentation comments are multiline or single-tine comments that begin with /// or /**. Using /// on consecutive lines has the
same effect as a multi-line doc comment.
Inside a documentation comment, the Dart compiler ignores all text unless its enclosed in brackets. Using brackets, you can refer to
classes, methods, fields, top-level variables, functions, ané parameters. The names in brackets are resolved inthe lexical scope of the
documented program element.
Here is an example of documentation comments with references to other classes and arguments:UI A donesticated South American comeLid (Lama gloma).
Ws
//1 Andean cultures have used Llanas as meat and pack
U/1 animals since pre-Hispanic tines
class Llama (
String nane;
U1 Feeds your Llama [Food]
UW
/// The typical. Llona eats one bale of hay per week.
void feed(Food food) {
uw
U1 bxercises your Ltana with an [activity] for
U1 [eimeltmit] minutes.
void exercise(Activity activity, int tineLinit) {
In the generated documentation, (Faod] becomes a link tothe API docs forthe Food class
To parse Dart code and generate HTML documentation, you can use the SDKs documentation generation tool.” Foran example of
generated documentation, see the Dart AP| documentation. ” For advice on how to structure your comments, see Guidelines for Dart
Doc Comments. (/guides/tanguage/effective-dart/documentation)
Summary
This page summarized the commonly used features inthe Dart language. More features are being implemented, but we expect that
they won't break existing code, For more information, see the Dart Language Specification (/gides/language/spec) and Effective Dart
Uguidesslanguageletfective-dartTo learn more about Dart’s core libraries, see A Tour ofthe Dart Libraries (/guidesylibraries/ibrary-tour)