Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions examples/misc/lib/language_tour/classes/enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,26 @@ void main() {
print(Color.blue.name); // 'blue'
// #enddocregion name
}

// #docregion enhanced
enum Vehicle implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});

final int tires;
final int passengers;
final int carbonPerKilometer;

int get carbonFootprint => (carbonPerKilometer / passengers).round();

@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}
// #enddocregion enhanced
35 changes: 35 additions & 0 deletions examples/misc/lib/samples/spacecraft.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,38 @@ abstract class Describable {
print('=========');
}
}
// #enddocregion abstract

// #docregion simple-enum
enum PlanetType { terrestrial, gas, ice }
// #enddocregion simple-enum

// #docregion enhanced-enum
/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// #enddocregion enhanced-enum
earth(planetType: PlanetType.terrestrial, moons: 1, hasRings: false),
mars(planetType: PlanetType.terrestrial, moons: 2, hasRings: false),
jupiter(planetType: PlanetType.gas, moons: 80, hasRings: true),
saturn(planetType: PlanetType.gas, moons: 83, hasRings: true),
// #docregion enhanced-enum
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);

/// A constant generating constructor
const Planet(
{required this.planetType, required this.moons, required this.hasRings});

/// All instance variables are final
final PlanetType planetType;
final int moons;
final bool hasRings;

/// Enhanced enums support getters and other methods
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}
// #enddocregion enhanced-enum
2 changes: 1 addition & 1 deletion examples/misc/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: examples
description: dart.dev example code.

environment:
sdk: ">=2.16.0 <3.0.0"
sdk: ">=2.17.0-0 <3.0.0"

dependencies:
args: ^2.3.0
Expand Down
14 changes: 14 additions & 0 deletions examples/misc/test/samples_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,20 @@ void main() {
]));
});

test('use enum', () {
void testIsGiant() {
// #docregion use-enum
final yourPlanet = Planet.earth;

if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}
// #enddocregion use-enum
}

expect(testIsGiant, m.prints('Your planet is not a "giant planet".'));
});

test('extends', () {
final o = Orbiter('O', someDate, 42);
expect(o.launchYear, someDate.year);
Expand Down
79 changes: 70 additions & 9 deletions src/_guides/language/language-tour.md
Original file line number Diff line number Diff line change
Expand Up @@ -3333,7 +3333,7 @@ abstract class AbstractContainer {
}
```


<a id="interfaces"></a>
### Implicit interfaces

Every class implicitly defines an interface containing all the instance
Expand Down Expand Up @@ -3529,9 +3529,16 @@ a fixed number of constant values.

{{site.alert.note}}
All enums automatically extend the [`Enum`][] class.
They are also sealed,
meaning they cannot be subclassed, implemented, mixed in,
or otherwise explicitly instantiated.

Abstract classes and mixins can explicitly implement or extend `Enum`,
but unless they are then implemented by or mixed into an enum declaration,
no objects can actually implement the type of that class or mixin.
{{site.alert.end}}

#### Using enums
#### Declaring simple enums

To declare a simple enumerated type,
use the `enum` keyword and
Expand All @@ -3547,6 +3554,66 @@ enum Color { red, green, blue }
to help prevent copy-paste errors.
{{site.alert.end}}

#### Declaring enhanced enums

Dart also allows enum declarations to declare classes
with fields, methods, and const constructors
which are limited to a fixed number of known constant instances.

To declare an enhanced enum,
follow a syntax similar to normal [classes](#classes),
but with a few extra requirements:

* Instance variables must be `final`,
including those added by [mixins](#mixins).
* All [generative constructors](#constant-constructors) must be constant.
* [Factory constructors](#factory-constructors) can only return
one of the fixed, known enum instances.
* No other class can be extended as [`Enum`] is automatically extended.
* There cannot be overrides for `index`, `hashCode`, the equality operator `==`.
* A member named `values` cannot be declared in an enum,
as it would conflict with the automatically generated static `values` getter.
* All instances of the enum must be declared
in the beginning of the declaration,
and there must be at least one instance declared.

Here is an example that declares an enhanced enum
with multiple instances, instance variables,
a getter, and an implemented interface:

<?code-excerpt "misc/lib/language_tour/classes/enum.dart (enhanced)"?>
```dart
enum Vehicle implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});

final int tires;
final int passengers;
final int carbonPerKilometer;

int get carbonFootprint => (carbonPerKilometer / passengers).round();

@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}
```

To learn more about declaring enhanced enums,
see the section on [Classes](#classes).

{{site.alert.version-note}}
Enhanced enums require a [language version][] of at least 2.17.
{{site.alert.end}}

#### Using enums

Access the enumerated values like
any other [static variable](#static-variables):

Expand Down Expand Up @@ -3607,14 +3674,8 @@ use the `.name` property:
print(Color.blue.name); // 'blue'
```

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][].


<a id="mixins"></a>
### Adding features to a class: mixins

Mixins are a way of reusing a class's code in multiple class
Expand Down
60 changes: 60 additions & 0 deletions src/samples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,66 @@ including initializer lists, optional `new` and `const`, redirecting constructor
`factory` constructors, getters, setters, and much more.


## Enums

Enums are a way of enumerating a predefined set of values or instances
in a way which ensures that there cannot be any other instances of that type.

Here is an example of a simple `enum` that defines
a simple list of predefined planet types:

<?code-excerpt "misc/lib/samples/spacecraft.dart (simple-enum)"?>
```dart
enum PlanetType { terrestrial, gas, ice }
```

Here is an example of an enhanced enum declaration
of a class describing planets,
with a defined set of constant instances,
namely the planets of our own solar system.

<?code-excerpt "misc/lib/samples/spacecraft.dart (enhanced-enum)"?>
```dart
/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// ···
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);

/// A constant generating constructor
const Planet(
{required this.planetType, required this.moons, required this.hasRings});

/// All instance variables are final
final PlanetType planetType;
final int moons;
final bool hasRings;

/// Enhanced enums support getters and other methods
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}
```

You might use the `Planet` enum like this:

<?code-excerpt "misc/test/samples_test.dart (use enum)" plaster="none"?>
```dart
final yourPlanet = Planet.earth;

if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}
```

[Read more](/guides/language/language-tour#enums) about enums in Dart,
including enhanced enum requirements, automatically introduced properties,
accessing enumerated value names, switch statement support, and much more.


## Inheritance

Dart has single inheritance.
Expand Down