Dart News & Updates

Dart is an open-source, scalable programming language, with robust libraries and runtimes, for building web, server, and mobile apps.

Search This Blog

New site for dart news and articles, dart language tour now available.

Master the fundamentals of Dart before jumping into Flutter

Jeff Delaney avatar

Dart - The Full Course is designed to teach you the fundamentals of the Dart language to prepare you for a successful journey into Flutter.

🦄 What will I learn?

This course provides a tour of Dart and teaches essential concepts for Flutter developers. Here’s what you’ll get out of it…

  • 👨‍🎤 Become confident with the Dart language
  • 🐦 Get Prepared for Flutter
  • 🦺 Master null-safety
  • 🦾 Learn how to use the Dart CLI
  • 🕹️ Practice OOP and Functional Programming Concepts
  • 🌊 Asynchronous programming with Futures & Streams

🤔 Is this Course Right for Me?

This course is beginner level 🟢 and will walk you through the fundamentals of Dart. It is fast-paced and similar to my style on YouTube , but far more in-depth and followed in a long linear format.

When was the course last updated?

Updated October 13th, 2021 Dart 2.14

How do I enroll?

The first few videos are free , so just jump in. When you reach a paid module, you will be asked to pay for a single course or upgrade to PRO.

You have full access to this course 🎉

How to Enroll

Lifetime access for a blazingly low price

Upgrade to PRO

Unlock all Fireship content && bonus perks

01 Dart in 100 Seconds

Learn the fundamentals of Dart in 100 Seconds

02 Getting Started with Dart

How to install Dart on Windows, Mac, or Linux

03 Dart CLI

Run and compile Dart programs from the command line

04 Variables

Fundamentals of variables and common data types in Dart

05 Null Safety Explained

A practical guide to null safety in Dart

06 Control Flow

Review conditional statements, loops, and assertions

07 Operators

Review common operators in Dart

08 Functions

First-class Functions and Functional Programming in Dart

Use the array-like Dart List to manage a collection of objects

Use the dictionary-like Dart Map to manage key-value pairs

Code your first Dart class

12 Constructors

How to use Dart class constructors

13 Interfaces

How implicit interfaces work in Dart

How inheritance works in in Dart

Use mixins to extend specific behaviors to classes

16 Generics

Use generics to parameterize types

17 Packages

Deal with name conflicts when importing packages

Use a Future to handle a single async event

Use a Stream to handle multiple async events

包含空安全和稳定的 FFI 的 Dart 2.12 已发布。

  • 获取 Dart SDK
  • Codelabs 列表
  • Extension 方法
  • dart:io 库介绍
  • 如何使用 package
  • 常用 package 介绍
  • Package 文件结构
  • Futures、async 和 await
  • JavaScript 互调
  • HTTP 客户端和服务端应用
  • Dart 与 HTML 关联
  • 常用 Web 库和 package
  • 使用 IntelliJ 和 Android Studio
  • 在线运行 Dart 䝣码
  • dart analyze
  • dart compile
  • dart format
  • dart2js (prod JS)
  • dartaotruntime
  • dartdevc (dev JS)
  • build_runner 命令
  • 教程中的 DartPad: 最佳实践
  • 迁秝到 Dart 2
  • Web 应用迁移到 Dart 2
  • 已失效的 pub 命令
  • Dart 团队官方博客
  • DartPad (在线编辑器)
  • 免责条款 (Disclaimer)

A basic Dart program

Important concepts, default value, late variables, final and const, runes and grapheme clusters, the main() function, functions as first-class objects, anonymous functions, lexical scope, lexical closures, testing functions for equality, return values, arithmetic operators, equality and relational operators, type test operators, assignment operators, logical operators, bitwise and shift operators, conditional expressions, cascade notation, other operators, if and else, while and do-while, break and continue, switch and case, using class members, using constructors, getting an object’s type, instance variables, constructors, abstract classes, implicit interfaces, extending a class, extension methods, enumerated types, adding features to a class: mixins, class variables and methods, why use generics, using collection literals, using parameterized types with constructors, generic collections and the types they contain, restricting the parameterized type, using generic methods, using libraries, implementing libraries, handling futures, declaring async functions, handling streams, callable classes, single-line comments, multi-line comments, documentation comments, 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. For a briefer, less complete introduction to the language, see the language samples page .

To learn more about Dart’s core libraries, see the library tour . Whenever you want more details about a language feature, consult the Dart language specification .

The following code uses many of Dart’s most basic features:

Here’s what this program uses that applies to all (or almost all) Dart apps:

As you learn about the Dart language, keep these facts and concepts in mind:

Everything you can place in a variable is an object , and every object is an instance of a class . Even numbers, functions, and null are objects. With the exception of null (if you enable sound null safety ), all objects inherit from the Object class.

Although Dart is strongly typed, type annotations are optional because Dart can infer types. In the code above, number is inferred to be of type int .

If you enable null safety , variables can’t contain null unless you say they can. You can make a variable nullable by putting a question mark ( ? ) at the end of its type. For example, a variable of type int? might be an integer, or it might be null . If you know that an expression never evaluates to null but Dart disagrees, you can add ! to assert that it isn’t null (and to throw an exception if it is). An example: int x = nullableButNotNullInt!

When you want to explicitly say that any type is allowed, use the type Object? (if you’ve enabled null safety ), Object , or — if you must defer type checking until runtime — the special type dynamic .

Dart supports generic types, like List<int> (a list of integers) or List<Object> (a list of objects of any type).

Dart supports top-level functions (such as main() ), as well as functions tied to a class or object ( static and 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 to a class or object (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 .

Identifiers can start with a letter or underscore ( _ ), followed by any combination of those characters plus digits.

Dart has both expressions (which have runtime values) and statements (which don’t). For example, the conditional expression condition ? expr1 : expr2 has a value of expr1 or expr2 . Compare that to an if-else statement , which has no value. A statement often contains one or more expressions, but an expression can’t directly contain a statement.

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; a run-time error results in an exception being raised while the code executes.

The following table lists the words that the Dart language treats specially.

Avoid using these words as identifiers. However, if necessary, the keywords marked with superscripts can be identifiers:

Words with the superscript 1 are contextual keywords , which have meaning only in specific places. They’re valid identifiers everywhere.

Words with the superscript 2 are built-in identifiers . To simplify the task of porting JavaScript code to Dart, these keywords are valid identifiers in most places, but they can’t be used as class or type names, or as import prefixes.

Words with the superscript 3 are limited reserved words related to asynchrony support . You can’t use await or yield as an identifier in any function body marked with async , async* , or sync* .

All other words in the table are reserved words , which can’t be identifiers.

Here’s an example of creating a variable and initializing it:

Variables store references. The variable called name contains a reference to a String object with a value of “Bob”.

The type of the name variable is inferred to be String , but you can change that type by specifying it. If an object isn’t restricted to a single type, specify the Object type (or dynamic if necessary).

Another option is to explicitly declare the type that would be inferred:

Uninitialized variables that have a nullable type have an initial value of null . (If you haven’t opted into null safety , then every variable has a nullable type.) Even variables with numeric types are initially null, because numbers—like everything else in Dart—are objects.

If you enable null safety, then you must initialize the values of non-nullable variables before you use them:

You don’t have to initialize a local variable where it’s declared, but you do need to assign it a value before it’s used. For example, the following code is valid because Dart can detect that lineCount is non-null by the time it’s passed to print() :

Dart 2.12 added the late modifier, which has two use cases:

  • Declaring a non-nullable variable that’s initialized after its declaration.
  • Lazily initializing a variable.

Often Dart’s control flow analysis can detect when a non-nullable variable is set to a non-null value before it’s used, but sometimes analysis fails. Two common cases are top-level variables and instance variables: Dart often can’t determine whether they’re set, so it doesn’t try.

If you’re sure that a variable is set before it’s used, but Dart disagrees, you can fix the error by marking the variable as late :

When you mark a variable as late but initialize it at its declaration, then the initializer runs the first time the variable is used. This lazy initialization is handy in a couple of cases:

  • The variable might not be needed, and initializing it is costly.
  • You’re initializing an instance variable, and its initializer needs access to this .

In the following example, if the temperature variable is never used, then the expensive _readThermometer() function is never called:

If you never intend to change a variable, use final or const , either instead of var or in addition to a 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 class variable is initialized the first time it’s used.

Here’s an example of creating and setting a final variable:

You can’t change the value of a final variable:

Use const for variables that you want to be compile-time constants . If the const variable is at the class level, mark it static const . Where you declare the variable, set the value to a compile-time constant such as a number or string literal, a const variable, or the result of an arithmetic operation on constant numbers:

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.

You can omit const from the initializing expression of a const declaration, like for baz above. For details, see DON’T use const redundantly .

You can change the value of a non-final, non-const variable, even if it used to have a const value:

You can’t change the value of a const variable:

You can define constants that use type checks and casts ( is and as ), collection if , and spread operators ( ... and ...? ):

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:

  • Numbers ( int , double )
  • Strings ( String )
  • Booleans ( bool )
  • Lists ( List , also known as arrays )
  • Sets ( Set )
  • Maps ( Map )
  • Runes ( Runes ; often replaced by the characters API)
  • Symbols ( Symbol )
  • The value null ( Null )

This support includes the ability to create objects using literals. For example, 'this is a string' is a string literal, and true is a boolean literal.

Because every variable in Dart refers to an object—an instance of a class —you can usually use constructors to initialize variables. Some of the built-in types have their own constructors. For example, you can use the Map() constructor to create a map.

Some other types also have special roles in the Dart language:

  • Object : The superclass of all Dart classes except Null .
  • Future and Stream : Used in asynchrony support .
  • Iterable : Used in for-in loops and in synchronous generator functions .
  • Never : Indicates that an expression can never successfully finish evaluating. Most often used for functions that always throw an exception.
  • dynamic : Indicates that you want to disable static checking. Usually you should use Object or Object? instead.
  • void : Indicates that a value is never used. Often used as a return type.

The Object , Object? , Null , and Never classes have special roles in the class hierarchy, as described in the top-and-bottom section of Understanding null safety .

Dart numbers come in two flavors:

Integer values no larger than 64 bits, depending on the platform. On the Dart VM, values can be from -2 63 to 2 63 - 1. Dart that’s compiled to JavaScript uses JavaScript numbers, allowing values from -2 53 to 2 53 - 1.

64-bit (double-precision) floating-point numbers, as specified by the IEEE 754 standard.

Both int and double are subtypes of num . The num type includes basic operators such as +, -, /, and *, and is also where you’ll find abs() , ceil() , and floor() , among other methods. (Bitwise operators, such as >>, are defined in the int class.) If num and its subtypes don’t have what you’re looking for, the dart:math library might.

Integers are numbers without a decimal point. Here are some examples of defining integer literals:

If a number includes a decimal, it is a double. Here are some examples of defining double literals:

Integer literals are automatically converted to doubles when necessary:

Here’s how you turn a string into a number, or vice versa:

The int type specifies the traditional bitwise shift (<<, >>), AND (&), and OR (|) operators. For example:

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.

A Dart string ( String object) holds a sequence of UTF-16 code units. You can use either single or double quotes to create a string:

You can put the value of an expression inside a string by using ${ expression } . If the expression is an identifier, you can skip the {}. To get the string corresponding to an object, Dart calls the object’s toString() method.

You can concatenate strings using adjacent string literals or the + operator:

Another way to create a multi-line string: use a triple quote with either single or double quotation marks:

You can create a “raw” string by prefixing it with r :

See Runes and grapheme clusters for details on how to express Unicode characters in a string.

Literal strings are compile-time constants, as long as any interpolated expression is a compile-time constant that evaluates to null or a numeric, string, or boolean value.

For more information on using strings, see Strings and regular expressions .

To represent boolean values, Dart has a type named bool . Only two objects have type bool: the boolean literals true and false , which are both compile-time constants.

Dart’s type safety means that you can’t use code like if ( nonbooleanValue ) or assert ( nonbooleanValue ) . Instead, explicitly check for values, like this:

Perhaps the most common collection in nearly every programming language is the array , or ordered group of objects. In Dart, arrays are List objects, so most people just call them lists .

Dart list literals look like JavaScript array literals. Here’s a simple Dart list:

You can add a comma after the last item in a Dart collection literal. This trailing comma doesn’t affect the collection, but it can help prevent copy-paste errors.

Lists use zero-based indexing, where 0 is the index of the first value and list.length - 1 is the index of the last value. You can get a list’s length and refer to list values just as you would in JavaScript:

To create a list that’s a compile-time constant, add const before the list literal:

Dart 2.3 introduced the spread operator ( ... ) and the null-aware spread operator ( ...? ), which provide a concise way to insert multiple values into a collection.

For example, you can use the spread operator ( ... ) to insert all the values of a list into another list:

If the expression to the right of the spread operator might be null, you can avoid exceptions by using a null-aware spread operator ( ...? ):

For more details and examples of using the spread operator, see the spread operator proposal.

Dart also offers collection if and collection for , which you can use to build collections using conditionals ( if ) and repetition ( for ).

Here’s an example of using collection if to create a list with three or four items in it:

Here’s an example of using collection for to manipulate the items of a list before adding them to another list:

For more details and examples of using collection if and for , see the control flow collections proposal.

The List type has many handy methods for manipulating lists. For more information about lists, see Generics and Collections .

A set in Dart is an unordered collection of unique items. Dart support for sets is provided by set literals and the Set type.

Here is a simple Dart set, created using a set literal:

To create an empty set, use {} preceded by a type argument, or assign {} to a variable of type Set :

Add items to an existing set using the add() or addAll() methods:

Use .length to get the number of items in the set:

To create a set that’s a compile-time constant, add const before the set literal:

Sets support spread operators ( ... and ...? ) and collection if and for , just like lists do. For more information, see the list spread operator and list collection operator discussions.

For more information about sets, see Generics and Sets .

In general, a map is 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:

You can create the same objects using a Map constructor:

Add a new key-value pair to an existing map just as you would in JavaScript:

Retrieve a value from a map the same way you would in JavaScript:

If you look for a key that isn’t in a map, you get a null in return:

Use .length to get the number of key-value pairs in the map:

To create a map that’s a compile-time constant, add const before the map literal:

Maps support spread operators ( ... and ...? ) and collection if and for , just like lists do. For details and examples, see the spread operator proposal and the control flow collections proposal.

For more information about maps, see the generics section and the library tour’s coverage of the Maps API .

In Dart, runes expose the Unicode code points of a string. You can use the characters package to view or manipulate user-perceived characters, also known as Unicode (extended) grapheme clusters.

Unicode defines a unique numeric value for each letter, digit, and symbol used in all of the world’s writing systems. Because a Dart string is a sequence of UTF-16 code units, expressing Unicode code points within a string requires special syntax. The usual way to express a Unicode code point is \uXXXX , where XXXX is a 4-digit hexadecimal value. For example, the heart character (♥) is \u2665 . To specify more or less than 4 hex digits, place the value in curly brackets. For example, the laughing emoji (😆) is \u{1f606} .

If you need to read or write individual Unicode characters, use the characters getter defined on String by the characters package. The returned Characters object is the string as a sequence of grapheme clusters. Here’s an example of using the characters API:

The output, depending on your environment, looks something like this:

For details on using the characters package to manipulate strings, see the example and API reference for the characters package.

A Symbol object represents an operator or identifier declared 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 literal, which is just # followed by the identifier:

Symbol literals are compile-time constants.

Dart is a 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 of a Dart class as if it were a function. For details, see Callable classes .

Here’s an example of implementing a function:

Although Effective Dart recommends type annotations for public APIs , the function still works if you omit the types:

For functions that contain just one expression, you can use a shorthand syntax:

The => expr syntax is a shorthand for { return expr ; } . The => notation is sometimes referred to as arrow syntax.

A function can have any number of required positional parameters. These can be followed either by named parameters or by optional positional parameters (but not both).

You can use trailing commas when you pass arguments to a function or when you define function parameters.

Named parameters

Named parameters are optional unless they’re specifically marked as required .

When calling a function, you can specify named parameters using paramName : value . For example:

When defining a function, use { param1 , param2 , …} to specify named parameters:

Although named parameters are a kind of optional parameter, you can annotate them with required to indicate that the parameter is mandatory — that users must provide a value for the parameter. For example:

If someone tries to create a Scrollbar without specifying the child argument, then the analyzer reports an issue.

Optional positional parameters

Wrapping a set of function parameters in [] marks them as optional positional parameters:

Here’s an example of calling this function without the optional parameter:

And here’s an example of calling this function with the third parameter:

Default parameter values

Your function can use = to define default values for both named and positional parameters. The default values must be compile-time constants. If no default value is provided, the default value is null .

Here’s an example of setting default values for named parameters:

The next example shows how to set default values for positional parameters:

You can also pass lists or maps as default values. The following example defines a function, doStuff() , that specifies a default list for the list parameter and a default map for the gifts parameter.

Every app must have a top-level main() function, which serves as the entrypoint to the app. The main() function returns void and has an optional List<String> parameter for arguments.

Here’s a simple main() function:

Here’s an example of the main() function for a command-line app that takes arguments:

You can use the args library to define and parse command-line arguments.

You can pass a function as a parameter to another function. For example:

You can also assign a function to a variable, such as:

This example uses an anonymous function. More about those in the next section.

Most functions are named, such as main() or printElement() . You can also create a nameless function called an anonymous function , or 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 optional type annotations, between parentheses.

The code block that follows contains the function’s body:

([[ Type ] param1 [, …]]) {    codeBlock ; };

The following example defines an anonymous function with an untyped parameter, item . The function, invoked for each item in the list, prints a string that includes the value at the specified index.

Click Run to execute the code.

If the function contains only a single expression or return statement, you can shorten it using arrow notation. Paste the following line into DartPad and click Run to verify that it is functionally equivalent.

Dart is a 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 if a variable is in scope.

Here is an example of nested functions with variables at each scope level:

Notice how nestedFunction() can use variables from every level, all the way up to the top level.

A closure is a function object that has access to variables in its lexical scope, even when the function is used outside of its original scope.

Functions can close over variables defined in surrounding scopes. In the following example, makeAdder() captures the variable addBy . Wherever the returned function goes, it remembers addBy .

Here’s an example of testing top-level functions, static methods, and instance methods for equality:

All functions return a value. If no return value is specified, the statement return null; is implicitly appended to the function body.

Dart supports the operators shown in the following table. You can implement many of these operators as class members .

When you use operators, you create expressions. Here are some examples of operator expressions:

In the operator table , each operator has higher precedence than the operators in the rows that follow it. For example, the multiplicative operator % 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:

Dart supports the usual arithmetic operators, as shown in the following table.

Dart also supports both prefix and postfix increment and decrement operators.

The following table lists the meanings of equality and relational operators.

To test whether two objects x and y represent the same thing, use the == operator. (In the rare case where you need to know whether two objects are the exact same object, use the identical() function instead.) Here’s how the == operator works:

If x or y is null, return true if both are null, and false if only one is null.

Return the result of the method invocation x .==( y ) . (That’s right, operators such as == are methods that are invoked on their first operand. For details, see Operators .)

Here’s an example of using each of the equality and relational operators:

The as , is , and is! operators are handy for checking types at runtime.

The result of obj is T is true if obj implements the interface specified by T . For example, obj is Object is always true.

Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type. Example:

If you aren’t sure that the object is of type T , then use is T to check the type before using the object.

As you’ve already seen, you can assign values using the = operator. To assign only if the assigned-to variable is null, use the ??= operator.

Compound assignment operators such as += combine an operation with an assignment.

Here’s how compound assignment operators work:

The following example uses assignment and compound assignment operators:

You can invert or combine boolean expressions using the logical operators.

Here’s an example of using the logical operators:

You can manipulate the individual bits of numbers in Dart. Usually, you’d use these bitwise and shift operators with integers.

Here’s an example of using bitwise and shift operators:

Dart has two operators that let you concisely evaluate expressions that might otherwise require if-else statements:

When you need to assign a value based on a boolean expression, consider using ? and : .

If the boolean expression tests for null, consider using ?? .

The previous example could have been written at least two other ways, but not as succinctly:

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:

The constructor, Paint() , returns a Paint object. The code that follows the cascade notation operates on this object, ignoring any values that might be returned.

The previous example is equivalent to this code:

If the object that the cascade operates on can be null, then use a null-shorting cascade ( ?.. ) for the first operation. Starting with ?.. guarantees that none of the cascade operations are attempted on that null object.

The previous code is equivalent to the following:

You can also nest cascades. For example:

Be careful to construct your cascade on a function that returns an actual object. For example, the following code fails:

The sb.write() call returns void, and you can’t construct a cascade on void .

You’ve seen most of the remaining operators in other examples:

For more information about the . , ?. , and .. operators, see Classes .

Control flow statements

You can control the flow of your Dart code using any of the following:

  • if and else
  • while and do - while loops
  • break and continue
  • switch and case

You can also affect the control flow using try-catch and throw , as explained in Exceptions .

Dart supports if statements with optional else statements, as the next sample shows. Also see conditional expressions .

Unlike JavaScript, conditions must use boolean values, nothing else. See Booleans for more information.

You can iterate with the standard for loop. For example:

Closures inside of Dart’s for loops capture the value of the index, avoiding a common pitfall found in JavaScript. For example, consider:

The output is 0 and then 1 , as expected. In contrast, the example would print 2 and then 2 in JavaScript.

If the object that you are iterating over is an Iterable, you can use the forEach() method. Using forEach() is a good option if you don’t need to know the current iteration counter:

Iterable classes such as List and Set also support the for-in form of iteration :

A while loop evaluates the condition before the loop:

A do - while loop evaluates the condition after the loop:

Use break to stop looping:

Use continue to skip to the next loop iteration:

You might write that example differently if you’re using an Iterable such as a list or set:

Switch statements in Dart compare integer, string, or compile-time constants using == . The compared objects must all be instances of the same class (and not of any of its subtypes), and the class must not override == . Enumerated types work well in switch statements.

Each non-empty case clause ends with a break statement, as a rule. Other valid ways to end a non-empty case clause are a continue , throw , or return statement.

Use a default clause to execute code when no case clause matches:

The following example omits the break statement in a case clause, thus generating an error:

However, Dart does support empty case clauses, allowing a form of fall-through:

If you really want fall-through, you can use a continue statement and a label:

A case clause can have local variables, which are visible only inside the scope of that clause.

During development, use an assert statement — assert( condition , optionalMessage ) ; — to disrupt normal execution if a boolean condition is false. You can find examples of assert statements throughout this tour. Here are some more:

To attach a message to an assertion, add a string as the second argument to assert (optionally with a trailing comma ):

The first argument to assert can be any expression that resolves to a boolean value. If the expression’s value is true, the assertion succeeds and execution continues. If it’s false, the assertion fails and an exception (an AssertionError ) is thrown.

When exactly do assertions work? That depends on the tools and framework you’re using:

  • Flutter enables assertions in debug mode.
  • Development-only tools such as dartdevc typically enable assertions by default.
  • Some tools, such as dart and dart2js, support assertions through a command-line flag: --enable-asserts .

In production code, assertions are ignored, and the arguments to assert aren’t evaluated.

Your Dart code can throw and catch exceptions. Exceptions are errors indicating that something unexpected happened. If the exception isn’t caught, the isolate that raised the exception is suspended, and typically the isolate and its program are terminated.

In contrast to Java, all of Dart’s exceptions are unchecked exceptions. Methods don’t declare which exceptions they might throw, and you aren’t 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.

Here’s an example of throwing, or raising , an exception:

You can also throw arbitrary objects:

Because throwing an exception is an expression, you can throw exceptions in => statements, as well as anywhere else that allows expressions:

Catching, or capturing, an exception stops the exception from propagating (unless you rethrow the exception). Catching an exception gives you a chance to handle it:

To handle code that can throw more than one type of exception, you can specify multiple catch clauses. The first catch clause that matches the thrown object’s type handles the exception. If the catch clause does not specify a type, that clause can handle any type of thrown object:

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 first is the exception that was thrown, and the second is the stack trace (a StackTrace object).

To partially handle an exception, while allowing it to propagate, use the rethrow keyword.

To ensure that some code runs whether or not an exception is thrown, use a finally clause. If no catch clause matches the exception, the exception is propagated after the finally clause runs:

The finally clause runs after any matching catch clauses:

Learn more by reading the Exceptions section of the library tour.

Dart is an object-oriented language with classes and mixin-based inheritance. Every object is an instance of a class, and all classes except Null descend from Object . Mixin-based inheritance means that although every class (except for the top class , Object? ) has exactly one superclass, a class body can be reused in multiple class hierarchies. Extension methods are a way to add functionality to a class without changing the class or creating a subclass.

Objects have members consisting of functions and data ( methods and instance variables , respectively). When you call a method, you invoke it on an object: the method has access to that object’s functions and data.

Use a dot ( . ) to refer to an instance variable or method:

Use ?. instead of . to avoid an exception when the leftmost operand is null:

You can create an object using a constructor . Constructor names can be either ClassName or ClassName . identifier . For example, the following code creates Point objects using the Point() and Point.fromJson() constructors:

The following code has the same effect, but uses the optional new keyword before the constructor name:

Some classes provide constant constructors . To create a compile-time constant using a constant constructor, put the const keyword before the constructor name:

Constructing two identical compile-time constants results in a single, canonical instance:

Within a constant context , you can omit the const before a constructor or literal. For example, look at this code, which creates a const map:

You can omit all but the first use of the const keyword:

If a constant constructor is outside of a constant context and is invoked without const , it creates a non-constant object :

To get an object’s type at runtime, you can use the Object property runtimeType , which returns a Type object.

Up to here, you’ve seen how to use classes. The rest of this section shows how to implement classes.

Here’s how you declare instance variables:

All uninitialized instance variables have the value null .

All instance variables generate an implicit getter method. Non-final instance variables and late final instance variables without initializers also generate an implicit setter method. For details, see Getters and setters .

If you initialize a non- late instance variable where it’s declared, the value is set when the instance is created, which is before the constructor and its initializer list execute.

Instance variables can be final , in which case they must be set exactly once. Initialize final , non- late instance variables at declaration, using a constructor parameter, or using a constructor’s initializer list :

If you want to assign the value of a final instance variable after the constructor body starts, you can use late final , but be careful .

Declare a constructor by creating a 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:

The this keyword refers to the current instance.

The pattern of assigning a constructor argument to an instance variable is so common, Dart has syntactic sugar to make it easy:

Default constructors

If you 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 superclass.

Constructors aren’t inherited

Subclasses don’t inherit constructors from their superclass. A subclass that declares no constructors has only the default (no argument, no name) constructor.

Named constructors

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

Remember that constructors are not inherited, which means that a superclass’s named constructor is not inherited by a subclass. If you want a subclass to be created with a named constructor defined in the 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’s unnamed, no-argument constructor. The superclass’s constructor is called at the beginning of the constructor body. If an initializer list is also being used, it executes before the superclass is called. In summary, the order of execution is as follows:

  • initializer list
  • superclass’s no-arg constructor
  • main class’s no-arg constructor

If the superclass doesn’t have an unnamed, no-argument constructor, then you must manually call one of the constructors in the superclass. Specify the superclass constructor after a colon ( : ), just before the constructor body (if any).

In the following example, the constructor for the Employee class calls the named constructor for its superclass, Person. Click Run to execute the code.

Because the arguments to the superclass constructor are evaluated before invoking the constructor, an argument can be an expression such as a function call:

Initializer list

Besides invoking a superclass constructor, you can also initialize instance variables before the constructor body runs. Separate initializers with commas.

During development, you can validate inputs by using assert in the initializer list.

Initializer lists are handy when setting up final fields. The following example initializes three final fields in an initializer list. Click Run to execute the code.

Redirecting constructors

Sometimes a constructor’s only purpose is to redirect to another constructor in the same class. A redirecting constructor’s body is empty, with the constructor call appearing after a colon (:).

Constant constructors

If 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 variables are final .

Constant constructors don’t always create constants. For details, see the section on using constructors .

Factory constructors

Use the factory keyword when implementing a constructor that doesn’t always create a new instance of its class. For example, a factory constructor might return an instance from a cache, or it might return an instance of a subtype. Another use case for factory constructors is initializing a final variable using logic that can’t be handled in the initializer list.

In the following example, the Logger factory constructor returns objects from a cache, and the Logger.fromJson factory constructor initializes a final variable from a JSON object.

Invoke a factory constructor just like you would any other constructor:

Methods are functions that provide behavior for an object.

Instance methods

Instance methods on objects can access instance variables and this . The distanceTo() method in the following sample is an example of an instance method:

Operators are instance methods with special names. Dart allows you to define operators with the following names:

An operator declaration is identified using the built-in identifier operator . The following example defines vector addition ( + ) and subtraction ( - ):

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:

With getters and setters, you can start with instance variables, later wrapping them with methods, all without changing client code.

Abstract methods

Instance, getter, and setter methods can be abstract, defining an interface but leaving its implementation up to other classes. Abstract methods can only exist in abstract classes .

To make a method abstract, use a semicolon (;) instead of a method body:

Use the abstract modifier to define an abstract class —a class that can’t be instantiated. Abstract classes are useful for defining interfaces, often with some implementation. If 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:

Every class implicitly defines an interface containing all the instance members of the class and of any interfaces it implements. If you want to create a class A that supports class B’s API without inheriting B’s implementation, class A should implement the B interface.

A class implements one or more interfaces by declaring them in an implements clause and then providing the APIs required by the interfaces. For example:

Here’s an example of specifying that a class implements multiple interfaces:

Use extends to create a subclass, and super to refer to the superclass:

Overriding members

Subclasses can override instance methods (including operators ), getters, and setters. You can use the @override annotation to indicate that you are intentionally overriding a member:

To narrow the type of a method parameter or instance variable in code that is type safe , you can use the covariant keyword .

noSuchMethod()

To detect or react whenever code attempts to use a non-existent method or instance variable, you can override noSuchMethod() :

You can’t invoke an unimplemented method unless one of the following is true:

The receiver has the static type dynamic .

The receiver has a static type that defines the unimplemented method (abstract is OK), and the dynamic type of the receiver has an implemention of noSuchMethod() that’s different from the one in class Object .

For more information, see the informal noSuchMethod forwarding specification.

Extension methods are a way to add functionality to existing libraries. You might use extension methods without even knowing it. For example, when you use code completion in an IDE, it suggests extension methods alongside regular methods.

Here’s an example of using an extension method on String named parseInt() that’s defined in string_apis.dart :

For details of using and implementing extension methods, see the extension methods page .

Enumerated types, often called enumerations or enums , are a special kind of class used to represent a fixed number of constant values.

Using enums

Declare an enumerated type using the enum keyword:

You can use trailing commas when declaring an enumerated type.

Each value in an enum has an index getter, which returns the zero-based position of the value in the enum declaration. For example, the first value has index 0, and the second value has index 1.

To get a list of all of the values in the enum, use the enum’s values constant.

You can use enums in switch statements , and you’ll get a warning if you don’t handle all of the enum’s values:

Enumerated types have the following limits:

  • You can’t subclass, mix in, or implement an enum.
  • You can’t explicitly instantiate an enum.

For more information, see the Dart language specification .

Mixins are a way of reusing a class’s code in multiple class 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:

To implement a mixin, create a class that extends Object and declares no constructors. Unless you want your mixin to be usable as a regular class, use the mixin keyword instead of class . For example:

Sometimes you might want to restrict the types that can use a mixin. For example, the mixin might depend on being able to invoke a method that the mixin doesn’t define. As the following example shows, you can restrict a mixin’s use by using the on keyword to specify the required superclass:

In the preceding code, only classes that extend or implement the Musician class can use the mixin MusicalPerformer . Because SingerDancer extends Musician , SingerDancer can mix in MusicalPerformer .

Use the static keyword to implement class-wide variables and methods.

Static variables

Static variables (class variables) are useful for class-wide state and constants:

Static variables aren’t initialized until they’re used.

Static methods

Static methods (class methods) don’t operate on an instance, and thus don’t have access to this . They do, however, have access to static variables. As the following example shows, you invoke static methods directly on a class:

You can use static methods as compile-time constants. For example, you can pass a static method as a parameter to a constant constructor.

If you look at the API documentation for the basic array type, List , you’ll see that the type is actually List<E> . The <…> notation marks List as a generic (or parameterized ) type—a type that has formal type parameters. By convention , most type variables have single-letter names, such as E, T, S, K, and V.

Generics are often required for type safety, but they have more benefits than just allowing your code to run:

  • Properly specifying generic types results in better generated code.
  • You can use generics to reduce code duplication.

If you intend for a list to contain only strings, you can declare it as List<String> (read that as “list of string”). That way you, your fellow programmers, and your tools can detect that assigning a non-string to the list is probably a mistake. Here’s an example:

Another reason for using generics is to reduce code duplication. Generics let you share a single interface and implementation between many types, while still taking advantage of static analysis. For example, say you create an interface for caching an object:

You discover that you want a string-specific version of this interface, so you create another interface:

Later, you decide you want a number-specific version of this interface… You get the idea.

Generic types can save you the trouble of creating all these interfaces. Instead, you can create a single interface that takes a type parameter:

In this code, T is the stand-in type. It’s a placeholder that you can think of as a type that a developer will define later.

List, set, and map literals can be parameterized. Parameterized literals are just like the literals you’ve already seen, except that you add < type > (for lists and sets) or < keyType , valueType > (for maps) before the opening bracket. Here is an example of using typed literals:

To specify one or more types when using a constructor, put the types in angle brackets ( <...> ) just after the class name. For example:

The following code creates a map that has integer keys and values of type View:

Dart generic types are reified , which means that they carry their type information around at runtime. For example, you can test the type of a collection:

When implementing a generic type, you might want to limit the types of its parameters. You can do this using extends .

It’s OK to use SomeBaseClass or any of its subclasses as generic argument:

It’s also OK to specify no generic argument:

Specifying any non- SomeBaseClass type results in an error:

Initially, Dart’s generic support was limited to classes. A newer syntax, called generic methods , allows type arguments on methods and functions:

Here the generic type parameter on first ( <T> ) allows you to use the type argument T in several places:

  • In the function’s return type ( T ).
  • In the type of an argument ( List<T> ).
  • In the type of a local variable ( T tmp ).

Libraries and visibility

The import and library directives can help you create a modular and shareable code base. Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore ( _ ) are visible only inside the library. Every Dart app is a library , even if it doesn’t use a library directive.

Libraries can be distributed using packages .

Use import to specify how a namespace from one library is used in the scope of another library.

For example, Dart web apps generally use the dart:html library, which they can import like this:

The only required argument to import is a URI specifying the library. For built-in libraries, the URI has the special dart: scheme. For other libraries, you can use a file system path or the package: scheme. The package: scheme specifies libraries provided by a package manager such as the pub tool. For example:

Specifying a library prefix

If you import two libraries that have conflicting identifiers, then you can specify a prefix for one or both libraries. For example, if library1 and library2 both have an Element class, then you might have code like this:

Importing only part of a library

If you want to use only part of a library, you can selectively import the library. For example:

Lazily loading a library

Deferred loading (also called lazy loading ) allows a web app to load a library on demand, if and when the library is needed. Here are some cases when you might use deferred loading:

  • To reduce a web app’s initial startup time.
  • To perform A/B testing—trying out alternative implementations of an algorithm, for example.
  • To load rarely used functionality, such as optional screens and dialogs.

To lazily load a library, you must first import it using deferred as .

When you need the library, invoke loadLibrary() using the library’s identifier.

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 loadLibrary() multiple times on a library without problems. The library is loaded only once.

Keep in mind the following when you use deferred loading:

  • A deferred library’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 in the importing file. Instead, consider moving interface types to a library imported by both the deferred library and the importing file.
  • Dart implicitly inserts loadLibrary() into the namespace that you define using deferred as namespace . The loadLibrary() function returns a Future .

See Create Library Packages for advice on how to implement a library package, including:

  • How to organize library source code.
  • How to use the export directive.
  • When to use the part directive.
  • When to use the library directive.
  • How to use conditional imports and exports to implement a library that supports multiple platforms.

Asynchrony support

Dart libraries are full of functions that return Future or Stream objects. These functions are asynchronous : they return after setting up a possibly time-consuming operation (such as I/O), without waiting for that operation to complete.

The async and await keywords support asynchronous programming, letting you write asynchronous code that looks similar to synchronous code.

When you need the result of a completed Future, you have two options:

  • Use async and await .
  • Use the Future API, as described in the library tour .

Code that uses async and await is asynchronous, but it looks a lot like synchronous code. For example, here’s some code that uses await to wait for the result of an asynchronous function:

To use await , code must be in an async function—a function marked as async :

Use try , catch , and finally to handle errors and cleanup in code that uses await :

You can use await multiple times in an async function. For example, the following code waits three times for the results of functions:

In await expression , the value of expression is usually a Future; if it isn’t, then the value is automatically wrapped in a Future. This Future object indicates a promise to return an object. The value of await expression is that returned object. The await expression makes execution pause until that object is available.

If you get a compile-time error when using await , make sure await is in an async function. For example, to use await in your app’s main() function, the body of main() must be marked as async :

An async function is a function whose body is marked with the async modifier.

Adding the async keyword to a function makes it return a Future. For example, consider this synchronous function, which returns a String:

If you change it to be an async function—for example, because a future implementation will be time consuming—the returned value is a Future:

Note that the function’s body doesn’t need to use the Future API. Dart creates the Future object if necessary. If your function doesn’t return a useful value, make its return type Future<void> .

For an interactive introduction to using futures, async , and await , see the asynchronous programming codelab .

When you need to get values from a Stream, you have two options:

  • Use async and an asynchronous for loop ( await for ).
  • Use the Stream API, as described in the library tour .

An asynchronous for loop has the following form:

The value of expression must have type Stream. Execution proceeds as follows:

  • Wait until the stream emits a value.
  • Execute the body of the for loop, with the variable set to that emitted value.
  • Repeat 1 and 2 until the stream is closed.

To stop listening to the stream, you can use a break or return statement, which breaks out of the for loop and unsubscribes from the stream.

If you get a compile-time error when implementing an asynchronous for loop, make sure the await for is in an async function. For example, to use an asynchronous for loop in your app’s main() function, the body of main() must be marked as async :

For more information about asynchronous programming, in general, see the dart:async section of the library tour.

When you need to lazily produce a sequence of values, consider using a generator function . Dart has built-in support for two kinds of generator functions:

  • Synchronous generator: Returns an Iterable object.
  • Asynchronous generator: Returns a Stream object.

To implement a synchronous generator function, mark the function body as sync* , and use yield statements to deliver values:

To implement an asynchronous generator function, mark the function body as async* , and use yield statements to deliver values:

If your generator is recursive, you can improve its performance by using yield* :

To allow an instance of your Dart class to be called like a function, implement the call() method.

In the following example, the WannabeFunction class defines a call() function that takes three strings and concatenates them, separating each with a space, and appending an exclamation. Click Run to execute the code.

Most computers, even on mobile platforms, have multi-core CPUs. To take advantage of all those cores, developers traditionally use shared-memory threads running concurrently. However, shared-state concurrency is error prone and can lead to complicated code.

Instead of threads, all Dart code runs inside of isolates . Each isolate has its own memory heap, ensuring that no isolate’s state is accessible from any other isolate.

For more information, see the following:

  • Dart asynchronous programming: Isolates and event loops
  • dart:isolate API reference, including Isolate.spawn() and TransferableTypedData
  • Background parsing cookbook on the Flutter site
  • Isolate sample app

In Dart, functions are objects, just like strings and numbers are objects. A typedef , or function-type alias , gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.

Consider the following code, which doesn’t use a typedef:

Type information is lost when assigning f to compare . The type of f is (Object, Object) → int (where → means returns), yet the type of compare is Function. If we change the code to use explicit names and retain type information, both developers and tools can use that information.

Because typedefs are simply aliases, they offer a way to check the type of any function. For example:

Use metadata to give additional information about your code. A metadata annotation begins with the character @ , followed by either a reference to a compile-time constant (such as deprecated ) or a call to a constant constructor.

Two annotations are available to all Dart code: @deprecated and @override . For examples of using @override , see Extending a class . Here’s an example of using the @deprecated annotation:

You can define your own metadata annotations. Here’s an example of defining a @todo annotation that takes two arguments:

And here’s an example of using that @todo annotation:

Metadata can appear before a library, class, typedef, 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.

Dart supports single-line comments, multi-line comments, and documentation comments.

A single-line comment begins with // . Everything between // and the end of line is ignored by the Dart compiler.

A multi-line comment begins with /* and ends with */ . Everything between /* and */ is ignored by the Dart compiler (unless the comment is a documentation comment; see the next section). Multi-line comments can nest.

Documentation comments are multi-line or single-line 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 it is enclosed in brackets. Using brackets, you can refer to classes, methods, fields, top-level variables, functions, and parameters. The names in brackets are resolved in the lexical scope of the documented program element.

Here is an example of documentation comments with references to other classes and arguments:

In the generated documentation, [Food] becomes a link to the API docs for the Food class.

To parse Dart code and generate HTML documentation, you can use the SDK’s documentation generation tool. For an example of generated documentation, see the Dart API documentation. For advice on how to structure your comments, see Guidelines for Dart Doc Comments.

This page summarized the commonly used features in the 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 and Effective Dart .

To learn more about Dart’s core libraries, see A Tour of the Dart Libraries .

  • Tournament News
  • Event Information
  • Bracket Tree

More darts than ever in 2025 as PDC calendar released

The growth of the PDC circuit will continue in 2025, with next year's calendar now confirmed.

Dobey denies Menzies to claim thrilling PC19 victory

Chris Dobey doubled his 2024 title tally with a thrilling 8-6 victory over Cameron Menzies in Thursday's Players Championship 19 final in Milton Keynes.

Heta storms to second title of 2024 with PC18 victory

Damon Heta secured his second PDC ranking title of the year with a comprehensive 8-3 victory over Ryan Searle in Wednesday’s Players Championship 18 final in Milton Keynes.

2024 Players Championships 18-19 entries confirmed

Player entries have been confirmed for next week's Players Championship double-header, as the 2024 PDC ProTour season continues in Milton Keynes.

Resilient Rock sees off Cullen for Players Championship 17 title

Josh Rock won his third senior ranking title, and a second of 2024, as he defeated Joe Cullen 8-6 in the final of Players Championship 17.

Deadly De Decker sweeps to maiden ProTour title at PC16

Mike De Decker secured his maiden senior PDC title with a brilliant success in Players Championship 16.

Seventh heaven for Littler with Players Championship 15 victory

Luke Littler celebrated his seventh PDC title of 2024 on Wednesday, after closing out an 8-6 success against emerging Dutchman Wessel Nijman in a fascinating Players Championship 15 final.

BoyleSports World Grand Prix race latest ahead of PC15-17

Boylesports world grand prix.

The race to qualify for the 2024 BoyleSports World Grand Prix resumes with a Players Championship treble-header in Milton Keynes this week.

Stats Analysis: The unpredictability of the 2024 PDC ProTour

With 14 different winners from 14 Players Championship events in 2024 so far, PDC Stats Analyst Christopher Kempf examines the key numbers behind this remarkable record...

2024 Players Championship 15-17 entries confirmed

Player entries have been confirmed for next week's Players Championship treble-header, as the 2024 PDC ProTour season continues in Milton Keynes.

The ProTour is the PDC's series of tournaments for professional players, comprising the European Tour and Players Championship events.

Players Championship events and European Tour events are held from February-October.

Prize money won in ProTour events counts towards ProTour Order of Merit, which on a one-year-rolling basis provides qualifiers for European Tour events and seeds for Players Championship tournaments.

Prize money won on the European Tour and Players Championship events also count towards their own Orders of Merit, as well as the main PDC Order of Merit.

All Players Championship and European Tour events are streamed live on PDCTV .

  • Testimonials
  • Search Trip
  • Trans-Siberian Tours
  • Saint Petersburg
  • Northern Lights
  • Lake Baikal
  • Russia For Expats
  • Winter Trains
  • Arctic & North
  • Golden Ring
  • Russia Cruises
  • Trans-Mongolian
  • Sightseeing
  • Trans Siberian
  • Wildlife & Nature
  • The Snow Empire
  • Under 8 Days
  • Kid Friendly
  • Small Groups
  • Senior Travels
  • Expats Travel
  • Luxury Trains
  • Luxury Travels
  • Russian Cruises
  • Snowmobile Tours
  • Youth Travel
  • Why Book with Us
  • Sustainable Travel
  • At a glance
  • Dates & Rates
  • Terms & conditions

Browse tours by travel themes

Providing you with the best russian tours, our reviews, russian travel update.

Russia is open for international travelers regardless their citizenship/country of residence. Tourist visas are being issued in the USA, Australia, New Zealand, Canada, the UK, EU, Japan, and worldwide. Electronic visas (up to 16 days of stay, single entry) are available for the following nationals: Austria, Andorra, Bahrain, Belgium, Bulgaria, Cambodia, Croatia, Cyprus, China, Czech Republic, Democratic People's Republic of Korea, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, India, Indonesia, Iran, Ireland, Iceland, Italy, Japan, Kuwait, Latvia, Lithuania, Liechtenstein, Luxembourg, Malaysia, Malta, Mexico, Monaco, Myanmar, Netherlands, North Macedonia, Norway, Oman, Poland, Portugal, Philippines, Romania, San Marino, Saudi Arabia, Serbia, Singapore, Slovakia, Slovenia, Spain, Switzerland, Sweden, Taiwan, Turkey, Vatican, Vietnam.

You can bring foreign currency and exchange money freely in Russia. You can open a bank account and g et a debit card in one hour time, once you will have arrived, we assist.

Medical insurance is available for international travelers through Russian insurance companies.

International flights to Moscow and St Petersburg are available via Tbilisi (Georgia), Yerevan (Armenia), Baku (Azerbaijan), Istanbul (Turkey), Belgrade (Serbia), Dubai & Abu-Dhabi (UEA), Doha (Qatar), Algiers (Algeria),Tehran (Iran), Muscat (Oman), Cairo (Egypt), Astana & Almaty (Kazakhstan), Beijing, Shanghai, Guangzhou, Chengdu, Chongqing, Shenzhen, Qingdao & Xian (China), Delhi (India), Colombo (Sri-Lanka), Male (Maldives). Information changes frequently, please inquire.

Trans-Siberian travels can fly in/out Vladivostok via Beijing (China), Harbin (China), Bangkok (Thailand), Tashkent (Uzbekistan).

Trans-Siberians taking off in Irkutsk/Lake Baikal, fly to Bishkek (Kyrgyzstan), Dushanbe (Tadjikistan), Namangan (Uzbekistan), Osh (Uzbekistan), Beijing Daxing (China), Bangkok (Thailand), Ulaaanbaatar (Mongolia).

Explore the best travel destinations in Russia with our wide range of sightseeing tours to Moscow, St Petersburg, Golden Ring, Kazan; Northern Lights viewing tours; wildlife & nature tours to Lake Baikal tours, Altai, Kamchatka tours, Trans-Siberian train tours, and more. Find the best guided trips and expert planned Russian holidays 2023-2024.

Thank you! One of your our travel experts will contact you within 24 hours.

  • Sign up for newsletter

Visa

dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. Learn more .

Announcing Dart 3.5 and an updated Dart roadmap! Learn more

  • Introduction
  • Libraries & imports
  • Built-in types
  • Collections
  • Type system
  • Overview & usage
  • Pattern types
  • Applied tutorial
  • Error handling
  • Constructors
  • Extend a class
  • Extension methods
  • Extension types
  • Callable objects
  • Class modifiers for API maintainers
  • Asynchronous support
  • Sound null safety
  • Migrating to null safety
  • Understanding null safety
  • Unsound null safety
  • dart:convert
  • Iterable collections
  • Futures and error handling
  • Using streams
  • Creating streams
  • Documentation
  • How to use packages
  • Commonly used packages
  • Creating packages
  • Publishing packages
  • Writing package pages
  • Dependencies
  • Package layout conventions
  • Pub environment variables
  • Pubspec file
  • Troubleshooting pub
  • Verified publishers
  • Security advisories
  • What not to commit
  • Number representation
  • Google APIs
  • Multi-platform apps
  • Get started
  • Write command-line apps
  • Fetch data from the internet
  • Write HTTP servers
  • Libraries & packages
  • Google Cloud
  • Wasm compilation
  • Environment declarations
  • Objective-C & Swift interop
  • Java & Kotlin interop
  • Past JS interop
  • Web interop
  • IntelliJ & Android Studio
  • Dart DevTools
  • Troubleshooting DartPad
  • dart analyze
  • dart compile
  • dart create
  • dart format
  • dartaotruntime
  • Experiment flags
  • build_runner
  • Customizing static analysis
  • Fixing common type problems
  • Fixing type promotion failures
  • Linter rules
  • Diagnostic messages
  • Debugging web apps
  • Language cheatsheet
  • Breaking changes
  • Language evolution
  • Language specification
  • Dart 3 migration guide
  • JavaScript to Dart
  • Swift to Dart
  • API reference
  • DartPad (online editor)
  • Package site

Dart language specification

Use this page to find the formal Dart language specification. For a gentler introduction to Dart, see the language tour .

The Dart 3 language specification is in progress. You can find the in-progress specification in PDF format:

  • Latest, in-progress specification (produced from a LaTeX file )

New language features are typically described using informal language feature specifications in the dart-lang/language repo:

  • Accepted informal proposals
  • Drafts of potential features

The Dart 2 language specification is available in PDF format:

  • Formal specification (Dart 2.10)

For information on Dart versions 2.12 and later, which have support for null safety , check out the in-progress Dart 3 specification .

The formal Dart 1.x language specification is available from the Ecma International website:

  • Dart Programming Language Specification, 4 th Edition

Unless stated otherwise, the documentation on this site reflects Dart 3.5.0. Page last updated on 2024-04-11. View source or report an issue .

IMAGES

  1. Dart Language Tour

    dart language tour

  2. Dart

    dart language tour

  3. Dart Language Tour

    dart language tour

  4. Language Tour

    dart language tour

  5. Dart Language Tour

    dart language tour

  6. Dart Programing Language Tour

    dart language tour

VIDEO

  1. A Quick Tour of Dart

  2. Learn Dart Language

  3. Day 16: Break and Continue Statement in Dart

  4. Day 19: Map in Dart

  5. What is dart programming language?

  6. Introduction to Dart Programming

COMMENTS

  1. Dart basics

    This page provides a brief introduction to the Dart language through samples of its main features. To learn more about the Dart language, visit the in-depth, individual topic pages listed under Language in the left side menu.. For coverage of Dart's core libraries, check out the core library documentation.You can also check out the Dart cheatsheet, for a more interactive introduction.

  2. Tutorials

    Learn how to use the Dart language, tools, and APIs to build applications with these tutorials. Start with the basics, then move on to asynchronous programming, streams, packages, server-side apps, and more.

  3. Dart documentation

    How to write asynchronous Dart code that uses futures and the async and await keywords. Unless stated otherwise, the documentation on this site reflects Dart 3.5.0. Page last updated on 2024-05-14. View source or report an issue. Learn to use the Dart language and libraries.

  4. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on A basic Dart program from the Language Tour page.Dart Docs: https://dart.dev/guides/language/languag...

  5. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on Classes.Dart Docs: https://dart.dev/guides/language/language-tour#classesCC by 4.0 https://creativec...

  6. 30 Days of Dart Code: A Beginner-Friendly Journey in Coding

    Here's a sneak peek of the journey: The First 30 Days: Laying the Foundations. Day 1: Introduction to Dart: We start at the very beginning, setting up your environment and writing your first ...

  7. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on Built-in types from the Language Tour page.Dart Docs: https://dart.dev/guides/language/language-tour...

  8. Dart language tour now available

    April 19, 2012. Posted by Kathy Walrath. The first version of the Dart language tour is now available. We tried to keep it short, useful, and focused on language features, although we couldn't help but touch on a bit of the dart:core library. The tour should be useful both for learning about the language and as a reference for Dart idioms.

  9. Dart 101

    This course teaches you the fundamentals of Dart, the programming language for Flutter, with examples and exercises. You will learn null-safety, OOP, functional programming, asynchronous programming and more.

  10. Language tour

    Learn how to use Dart's features, from variables and operators to classes and libraries, with examples and explanations. This page covers the basics of Dart syntax, types, control flow, functions, and more.

  11. Learn Dart In A Week With These Free Resources

    Take the Dart Language Tour This should be the first link you should visit for learning Dart, it's the best place to get a good overview of the language. A tour of the Dart language

  12. The Dart language tour

    Class inheritance and abstract classes. Dart is an object-oriented language with a mixin-based inheritance model. This means that every class has exactly one superclass but can implement multiple classes as interfaces and use multiple class bodies (mixins). Every class is at least a subclass of the Object class.

  13. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on Important concepts and Keywords from the Language Tour page.Dart Docs: https://dart.dev/guides/langu...

  14. 9 Features I Love About the Dart Programming Language

    Dart is a modern, easy-to-learn language. You will feel right at home if you are familiar with languages like Java, C#, or Kotlin. When you want to dive in deeper, I recommend one or more of the following sites: The Dart Language Tour; Dart language samples; A guide to effective Dart programming

  15. Dart programming language

    Dart is an approachable, portable, and productive language for high-quality apps on any platform. Dart is an approachable, portable, and productive language for high-quality apps on any platform. dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. Learn more. OK, got it. menu ...

  16. Moscow Darts

    Moscow Dart Tournaments and Events.

  17. Dart overview

    Explore Dart in the browser through DartPad, a web-based execution environment for Dart code. Take a tour of the Dart language, which shows you how to use each major Dart feature. Complete a Dart tutorial that covers the basics of using Dart to build for the command line. Work through extensive online training from Dart experts.

  18. ProTour, Darts Tournaments

    2024 Players Championship 15-17 entries confirmed. Player entries have been confirmed for next week's Players Championship treble-header, as the 2024 PDC ProTour season continues in Milton Keynes. The PDC ProTour is a Tournament combining the European Tour and Players Championships. Make sure you book your ticket & watch this year!

  19. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on the main() function.Dart Docs: https://dart.dev/guides/language/language-tour#the-main-functionCC by...

  20. Geen Nederlands succes: Dirk van Duijvenbode kan zege op Luke Littler

    Dirk van Duijvenbode heeft het niet verder weten te schoppen dan de kwartfinales op de Flanders Darts Trophy, het tiende PDC Euro Tour-toernooi van het jaar. De Nederlander won zondagmiddag nog ...

  21. Best Russia Tours and Travel Packages 2024/2025

    Grand Russia UNESCO Tour 13 days from: $3,440 USD. Winter: Two Capitals And Baikal Ice 12 days from: $3,000 USD. show more Our reviews Charyn Krauze, USA "Discovery Russia took care of every single detail of our experience from the start to the finish of our trip. Excellent hotels in both locations we went to - Lake Baikal and St. Petersburg ...

  22. Dart Language Tour

    A guided and annotated Dart documentation walkthrough on Variables from the Language Tour page. This is the subsection on Late variables.Dart Docs: https://d...

  23. Patriot Park and Kubinka tank museum tour

    Duration: 7 hours Group: up to 35 Season: All year round Language: English Tour type: Museum tour, Military tour Tour price: from 9000 rub per person Patriot Park represents the unique, world's biggest collection of armed vehicles. The park, also known as the "Russian military Disneyland", is able to host tens of thousands of visitors per day. Patriot incorporates the world's

  24. Language specification

    The Dart 3 language specification is in progress. You can find the in-progress specification in PDF format: Latest, in-progress specification (produced from a LaTeX file) New language features are typically described using informal language feature specifications in the dart-lang/language repo: Accepted informal proposals.