Coding style
Last modified on Tue 09 Nov 2021
Style guidelines
- Use flutter auto-formatter on Save. Make sure you have
Preferences -> Editor -> General -> Strip trailing spaces on Save
set toModified Lines
andAlways keep trailing spaces on caret line
set totrue
. - Set max line lenght to 120. You can do this in
Preferences -> Editor -> Code Style -> Dart -> Wrapping and Braces -> Hard wrap at
. - To ensure that code conforms to style guidelines we use Dart static analysis. This linter helps us in maintaining a higher level of code discipline and increasing the code's reliability. All linter warnings should be considered and your code should be customized according to it.
- Use trailing comma at the end of a parameter list in functions, methods and constructors. If there is only one parameter, you can leave out the comma.
Good:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
);
}
Bad:
Widget build(BuildContext context) {
return MaterialApp(title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue));
}
Constants
- Use class to define your constants. Define multiple classes to break constants into logical sections.
- The class's constants should be written in lowercase.
// Definiton
class Fonts {
Fonts._();
static const String spaceGrotesk = 'SpaceGrotesk';
}
// Usage
Fonts.spaceGrotesk
- Define constants for magic numbers. They serve as documentation of the meaning of its value.
const double newtonUnit = 9.8;
double massInNewton(double massInKg) {
return massInKg * newtonUnit;
}
- You can also use constants to define some repeating layouting numbers (
MapScreen.buttonsWidth
). But, use this wisely! For example,SizedBoxes
often have different widht or height values and changing one constant can have undesired impact in the whole app.
Function notations
- Use fat-arrow rather than block syntax. If handlers are multi-liners, create a function.
Good:
void print(List<int> numbers) {
numbers.forEach((element) => printSqrt(element.toDouble()));
}
void printSqrt(double number) {
double sqrtValue = sqrt(number);
print(sqrtValue);
}
Bad:
void print(List<int> numbers) {
numbers.forEach((element) {
double value = element.toDouble();
double sqrtValue = sqrt(number);
print(sqrtValue);
});
}
- Use tear-off rather than fat-arrow.
Good:
strings.forEach(print);
Bad:
strings.forEach((element) => print(element));
Avoid large functions and widgets
- Split large function into smaller functions.
- Split large widget into multiple (private or reusable) widgets.
- Use widget class rather than function returning widget!
Good:
class _MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(child: Text('Hello, world!'));
}
}
void main() {
runApp(MaterialApp(
title: 'My app',
home: _MyScaffold(),
));
}
Bad:
Widget _myScaffold() {
return Material(child: Text('Hello, world!'));
}
void main() {
runApp(MaterialApp(
title: 'My app',
home: _myScaffold(),
));
}
Return and break early
- When you have to meet certain criteria to continue execution, try to exit early.
Good:
if (!n.isNumber) {
return;
}
// Use n here
Bad:
if (n.isNumber) {
// Use n here
} else {
return;
}
Comments
- Use comments when the code is not self-explanatory.
- Prefer commenting why something is done, rather than how.
- For doc comments use
///
. - Prefer writing doc comments for public APIs.
- Use square brackets in doc comments to refer to in-scope identifiers.
/// Throws a [StateError] if ...
/// similar to [anotherMethod()], but ...
- Don't forget to update commments when you change the commented code!
Imports
- Use relative paths instead of full paths.
Good:
import 'constants.dart';
Bad:
import 'package:flutter_myApp/constants.dart';