| OLD | NEW |
| 1 --- | 1 --- |
| 2 layout: article | 2 layout: article |
| 3 title: "Dart Style Guide" | 3 title: "Dart Style Guide" |
| 4 rel: | 4 rel: |
| 5 author: bob-nystrom | 5 author: bob-nystrom |
| 6 description: "Follow these guidelines for consistent, readable Dart code." | 6 description: "Follow these guidelines for consistent, readable Dart code." |
| 7 has-permalinks: true | 7 has-permalinks: true |
| 8 article: | 8 article: |
| 9 written_on: 2011-10-01 | 9 written_on: 2011-10-01 |
| 10 updated_on: 2013-10-04 | 10 updated_on: 2013-10-04 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 where there may be good reasons to on rare occasions. | 60 where there may be good reasons to on rare occasions. |
| 61 | 61 |
| 62 This sounds like the style police are going to beat down your door if you don't | 62 This sounds like the style police are going to beat down your door if you don't |
| 63 have your laces tied correctly. Things aren't that bad. Most of the guidelines | 63 have your laces tied correctly. Things aren't that bad. Most of the guidelines |
| 64 here are common sense and we're all reasonable people. The goal, as always, is | 64 here are common sense and we're all reasonable people. The goal, as always, is |
| 65 nice, readable and maintainable code. | 65 nice, readable and maintainable code. |
| 66 | 66 |
| 67 ## Types | 67 ## Types |
| 68 | 68 |
| 69 #### AVOID creating classes that contain only static members. | 69 #### AVOID creating classes that contain only static members. |
| 70 {:.no_toc} |
| 70 | 71 |
| 71 In Java and C#, all members must be in a class. In those languages, you | 72 In Java and C#, all members must be in a class. In those languages, you |
| 72 occasionally encounter classes that are basically namespaces: just bags of | 73 occasionally encounter classes that are basically namespaces: just bags of |
| 73 static members. Dart, like Python and JavaScript, doesn't have this limitation. | 74 static members. Dart, like Python and JavaScript, doesn't have this limitation. |
| 74 You are free to define variables and functions at the top level. | 75 You are free to define variables and functions at the top level. |
| 75 | 76 |
| 76 Name collisions, when they occur, can be avoided by importing a library using a | 77 Name collisions, when they occur, can be avoided by importing a library using a |
| 77 prefix. The advantage to this is that when collisions *don't* occur (which only | 78 prefix. The advantage to this is that when collisions *don't* occur (which only |
| 78 the *user* of a library knows, not the creator), the user doesn't have to fully | 79 the *user* of a library knows, not the creator), the user doesn't have to fully |
| 79 qualify the name at every callsite. | 80 qualify the name at every callsite. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 98 | 99 |
| 99 class GeometryUtils { | 100 class GeometryUtils { |
| 100 static num distance(num x1, num y1, num x2, num y2) { | 101 static num distance(num x1, num y1, num x2, num y2) { |
| 101 /* ... */ | 102 /* ... */ |
| 102 } | 103 } |
| 103 } | 104 } |
| 104 {% endprettify %} | 105 {% endprettify %} |
| 105 </div> | 106 </div> |
| 106 | 107 |
| 107 #### AVOID defining a one-member abstract class when a simple function will do. | 108 #### AVOID defining a one-member abstract class when a simple function will do. |
| 109 {:.no_toc} |
| 108 | 110 |
| 109 Unlike Java, Dart has first-class functions, closures, and a nice light syntax | 111 Unlike Java, Dart has first-class functions, closures, and a nice light syntax |
| 110 for using them. If all you need is something like a callback, just use a | 112 for using them. If all you need is something like a callback, just use a |
| 111 function. If you're defining an class and it only has a single abstract member | 113 function. If you're defining an class and it only has a single abstract member |
| 112 with a meaningless name like `call` or `invoke`, there is a good chance you | 114 with a meaningless name like `call` or `invoke`, there is a good chance you |
| 113 just want a function. | 115 just want a function. |
| 114 | 116 |
| 115 <div class="good"> | 117 <div class="good"> |
| 116 {% prettify dart %} | 118 {% prettify dart %} |
| 117 typedef bool Predicate(item); | 119 typedef bool Predicate(item); |
| 118 {% endprettify %} | 120 {% endprettify %} |
| 119 </div> | 121 </div> |
| 120 | 122 |
| 121 <div class="bad"> | 123 <div class="bad"> |
| 122 {% prettify dart %} | 124 {% prettify dart %} |
| 123 abstract class Predicate { | 125 abstract class Predicate { |
| 124 bool test(item); | 126 bool test(item); |
| 125 } | 127 } |
| 126 {% endprettify %} | 128 {% endprettify %} |
| 127 </div> | 129 </div> |
| 128 | 130 |
| 129 ## Members | 131 ## Members |
| 130 | 132 |
| 131 #### DO use constructors instead of static methods to create instances. | 133 #### DO use constructors instead of static methods to create instances. |
| 134 {:.no_toc} |
| 132 | 135 |
| 133 | 136 |
| 134 Constructors are invoked using `new` or `const` which communicates clearly at | 137 Constructors are invoked using `new` or `const` which communicates clearly at |
| 135 the callsite that an object is being created. Named constructors and factory | 138 the callsite that an object is being created. Named constructors and factory |
| 136 constructors in Dart give you all of the flexibility of static methods in other | 139 constructors in Dart give you all of the flexibility of static methods in other |
| 137 languages, while still allowing the callsite to appear like a regular | 140 languages, while still allowing the callsite to appear like a regular |
| 138 constructor invocation. | 141 constructor invocation. |
| 139 | 142 |
| 140 <div class="good"> | 143 <div class="good"> |
| 141 {% prettify dart %} | 144 {% prettify dart %} |
| (...skipping 11 matching lines...) Expand all Loading... |
| 153 {% prettify dart %} | 156 {% prettify dart %} |
| 154 class Point { | 157 class Point { |
| 155 num x, y; | 158 num x, y; |
| 156 Point(this.x, this.y); | 159 Point(this.x, this.y); |
| 157 static Point zero() => new Point(0, 0); | 160 static Point zero() => new Point(0, 0); |
| 158 } | 161 } |
| 159 {% endprettify %} | 162 {% endprettify %} |
| 160 </div> | 163 </div> |
| 161 | 164 |
| 162 #### DO use `;` instead of `{}` for empty constructor bodies. | 165 #### DO use `;` instead of `{}` for empty constructor bodies. |
| 166 {:.no_toc} |
| 163 | 167 |
| 164 | 168 |
| 165 In Dart, a constructor with an empty body can be terminated with just a | 169 In Dart, a constructor with an empty body can be terminated with just a |
| 166 semicolon. This is *required* for const constructors. For consistency and | 170 semicolon. This is *required* for const constructors. For consistency and |
| 167 brevity, other constructors should also do this. | 171 brevity, other constructors should also do this. |
| 168 | 172 |
| 169 <div class="good"> | 173 <div class="good"> |
| 170 {% prettify dart %} | 174 {% prettify dart %} |
| 171 class Point { | 175 class Point { |
| 172 int x, y; | 176 int x, y; |
| 173 Point(this.x, this.y); | 177 Point(this.x, this.y); |
| 174 } | 178 } |
| 175 {% endprettify %} | 179 {% endprettify %} |
| 176 </div> | 180 </div> |
| 177 | 181 |
| 178 <div class="bad"> | 182 <div class="bad"> |
| 179 {% prettify dart %} | 183 {% prettify dart %} |
| 180 class Point { | 184 class Point { |
| 181 int x, y; | 185 int x, y; |
| 182 Point(this.x, this.y) {} | 186 Point(this.x, this.y) {} |
| 183 } | 187 } |
| 184 {% endprettify %} | 188 {% endprettify %} |
| 185 </div> | 189 </div> |
| 186 | 190 |
| 187 #### DO place the `super()` call last in a constructor initialization list. | 191 #### DO place the `super()` call last in a constructor initialization list. |
| 192 {:.no_toc} |
| 188 | 193 |
| 189 | 194 |
| 190 Field initializers are evaluated in the order that they appear in the | 195 Field initializers are evaluated in the order that they appear in the |
| 191 constructor initialization list. If you place a `super()` call in the middle of | 196 constructor initialization list. If you place a `super()` call in the middle of |
| 192 an initializer list, the superclass's initializers will be evaluated right then | 197 an initializer list, the superclass's initializers will be evaluated right then |
| 193 before evaluating the rest of the subclass's initializers. | 198 before evaluating the rest of the subclass's initializers. |
| 194 | 199 |
| 195 What it *doesn't* mean is that the superclass's *constructor body* will be | 200 What it *doesn't* mean is that the superclass's *constructor body* will be |
| 196 executed then. That always happens after all initializers are run regardless of | 201 executed then. That always happens after all initializers are run regardless of |
| 197 where `super()` appears. It's vanishingly rare that the order of initializers | 202 where `super()` appears. It's vanishingly rare that the order of initializers |
| (...skipping 13 matching lines...) Expand all Loading... |
| 211 | 216 |
| 212 <div class="bad"> | 217 <div class="bad"> |
| 213 {% prettify dart %} | 218 {% prettify dart %} |
| 214 View(Style style, List children) | 219 View(Style style, List children) |
| 215 : super(style), | 220 : super(style), |
| 216 _children = children { | 221 _children = children { |
| 217 {% endprettify %} | 222 {% endprettify %} |
| 218 </div> | 223 </div> |
| 219 | 224 |
| 220 #### DO use a getter for operations that conceptually access a property. | 225 #### DO use a getter for operations that conceptually access a property. |
| 226 {:.no_toc} |
| 221 | 227 |
| 222 | 228 |
| 223 If the name of the method starts with `get` or is an adjective like `visible` or | 229 If the name of the method starts with `get` or is an adjective like `visible` or |
| 224 `empty` that's a sign you're better off using a getter. More specifically, you | 230 `empty` that's a sign you're better off using a getter. More specifically, you |
| 225 should use a getter instead of a method when it: | 231 should use a getter instead of a method when it: |
| 226 | 232 |
| 227 * **Does not take any arguments.** | 233 * **Does not take any arguments.** |
| 228 * **Returns a value.** | 234 * **Returns a value.** |
| 229 * **Is side-effect free.** Invoking a getter shouldn't change any | 235 * **Is side-effect free.** Invoking a getter shouldn't change any |
| 230 externally-visible state (caching internally or lazy initialization is | 236 externally-visible state (caching internally or lazy initialization is |
| (...skipping 11 matching lines...) Expand all Loading... |
| 242 | 248 |
| 243 <div class="bad"> | 249 <div class="bad"> |
| 244 {% prettify dart %} | 250 {% prettify dart %} |
| 245 num amount = accounts.sum; // may be slow to calculate | 251 num amount = accounts.sum; // may be slow to calculate |
| 246 DateTime timeStamp = DateTime.now; // returns different value each call | 252 DateTime timeStamp = DateTime.now; // returns different value each call |
| 247 window.refresh; // doesn't return a value | 253 window.refresh; // doesn't return a value |
| 248 {% endprettify %} | 254 {% endprettify %} |
| 249 </div> | 255 </div> |
| 250 | 256 |
| 251 #### DO use a setter for operations that conceptually change a property. | 257 #### DO use a setter for operations that conceptually change a property. |
| 258 {:.no_toc} |
| 252 | 259 |
| 253 | 260 |
| 254 If the name of the method starts with `set` that's often a sign that it could be | 261 If the name of the method starts with `set` that's often a sign that it could be |
| 255 a setter. More specifically, use a setter instead of a method when it: | 262 a setter. More specifically, use a setter instead of a method when it: |
| 256 | 263 |
| 257 * **Takes a single argument.** | 264 * **Takes a single argument.** |
| 258 * **Changes some state in the object.** | 265 * **Changes some state in the object.** |
| 259 * **Has a corresponding getter.** It feels weird for users to have state that | 266 * **Has a corresponding getter.** It feels weird for users to have state that |
| 260 they can modify but not see. (The converse is not true; it's fine to have | 267 they can modify but not see. (The converse is not true; it's fine to have |
| 261 getters that don't have setters.) | 268 getters that don't have setters.) |
| 262 * **Is idempotent.** Calling the same setter twice with the same value | 269 * **Is idempotent.** Calling the same setter twice with the same value |
| 263 should do nothing the second time. | 270 should do nothing the second time. |
| 264 * **Is fast.** Users expect expressions like `foo.bar = value` to execute quic
kly. | 271 * **Is fast.** Users expect expressions like `foo.bar = value` to execute quic
kly. |
| 265 | 272 |
| 266 <div class="good"> | 273 <div class="good"> |
| 267 {% prettify dart %} | 274 {% prettify dart %} |
| 268 rect.width = 3; | 275 rect.width = 3; |
| 269 button.visible = false; | 276 button.visible = false; |
| 270 {% endprettify %} | 277 {% endprettify %} |
| 271 </div> | 278 </div> |
| 272 | 279 |
| 273 #### AVOID wrapping fields in getters and setters just to be "safe". | 280 #### AVOID wrapping fields in getters and setters just to be "safe". |
| 281 {:.no_toc} |
| 274 | 282 |
| 275 | 283 |
| 276 In Java and C#, it's common to hide all fields behind getters and setters (or | 284 In Java and C#, it's common to hide all fields behind getters and setters (or |
| 277 properties in C#), even if the implementation just forwards to the field. That | 285 properties in C#), even if the implementation just forwards to the field. That |
| 278 way, if you ever need to do more work in those members, you can without needing | 286 way, if you ever need to do more work in those members, you can without needing |
| 279 to touch the callsites. This is because calling a getter method is different | 287 to touch the callsites. This is because calling a getter method is different |
| 280 than accessing a field in Java, and accessing a property isn't binary-compatible | 288 than accessing a field in Java, and accessing a property isn't binary-compatible |
| 281 with accessing a raw field in C#. | 289 with accessing a raw field in C#. |
| 282 | 290 |
| 283 Dart doesn't have this limitation. Fields and getters/setters are completely | 291 Dart doesn't have this limitation. Fields and getters/setters are completely |
| (...skipping 14 matching lines...) Expand all Loading... |
| 298 var _contents; | 306 var _contents; |
| 299 get contents => _contents; | 307 get contents => _contents; |
| 300 set contents(value) { | 308 set contents(value) { |
| 301 _contents = value; | 309 _contents = value; |
| 302 } | 310 } |
| 303 } | 311 } |
| 304 {% endprettify %} | 312 {% endprettify %} |
| 305 </div> | 313 </div> |
| 306 | 314 |
| 307 #### PREFER using a public final field instead of a private field with a public
getter. | 315 #### PREFER using a public final field instead of a private field with a public
getter. |
| 316 {:.no_toc} |
| 308 | 317 |
| 309 | 318 |
| 310 If you have a field that outside code should be able to see but not assign to | 319 If you have a field that outside code should be able to see but not assign to |
| 311 (and you don't need to set it outside of the constructor), a simple solution | 320 (and you don't need to set it outside of the constructor), a simple solution |
| 312 that works in many cases is to just mark it `final`. | 321 that works in many cases is to just mark it `final`. |
| 313 | 322 |
| 314 <div class="good"> | 323 <div class="good"> |
| 315 {% prettify dart %} | 324 {% prettify dart %} |
| 316 class Box { | 325 class Box { |
| 317 final contents = []; | 326 final contents = []; |
| 318 } | 327 } |
| 319 {% endprettify %} | 328 {% endprettify %} |
| 320 </div> | 329 </div> |
| 321 | 330 |
| 322 <div class="bad"> | 331 <div class="bad"> |
| 323 {% prettify dart %} | 332 {% prettify dart %} |
| 324 class Box { | 333 class Box { |
| 325 var _contents; | 334 var _contents; |
| 326 get contents => _contents; | 335 get contents => _contents; |
| 327 } | 336 } |
| 328 {% endprettify %} | 337 {% endprettify %} |
| 329 </div> | 338 </div> |
| 330 | 339 |
| 331 #### CONSIDER using `=>` to define members whose body returns the result of a si
ngle expression. | 340 #### CONSIDER using `=>` to define members whose body returns the result of a si
ngle expression. |
| 341 {:.no_toc} |
| 332 | 342 |
| 333 | 343 |
| 334 In addition to using `=>` for function expressions, Dart also lets you define | 344 In addition to using `=>` for function expressions, Dart also lets you define |
| 335 members with them. They are a good fit for simple members that just calculate | 345 members with them. They are a good fit for simple members that just calculate |
| 336 and return a value. | 346 and return a value. |
| 337 | 347 |
| 338 <div class="good"> | 348 <div class="good"> |
| 339 {% prettify dart %} | 349 {% prettify dart %} |
| 340 get width => right - left; | 350 get width => right - left; |
| 341 bool ready(num time) => minTime == null || minTime <= time; | 351 bool ready(num time) => minTime == null || minTime <= time; |
| 342 containsValue(String value) => getValues().contains(value); | 352 containsValue(String value) => getValues().contains(value); |
| 343 {% endprettify %} | 353 {% endprettify %} |
| 344 </div> | 354 </div> |
| 345 | 355 |
| 346 Members that don't fit on one line can still use `=>`, but if you find yourself | 356 Members that don't fit on one line can still use `=>`, but if you find yourself |
| 347 cramming a single expression into several continued lines, it is probably | 357 cramming a single expression into several continued lines, it is probably |
| 348 cleaner to just use a curly body with an explicit `return`. | 358 cleaner to just use a curly body with an explicit `return`. |
| 349 | 359 |
| 350 #### AVOID boolean arguments unless their meaning is completely obvious. | 360 #### AVOID boolean arguments unless their meaning is completely obvious. |
| 361 {:.no_toc} |
| 351 | 362 |
| 352 | 363 |
| 353 Unlike other types, booleans are usually used in literal form. Things like | 364 Unlike other types, booleans are usually used in literal form. Things like |
| 354 numbers are usually wrapped in named constants, but we usually just pass around | 365 numbers are usually wrapped in named constants, but we usually just pass around |
| 355 `true` and `false` directly. That can make callsites unreadable if it isn't | 366 `true` and `false` directly. That can make callsites unreadable if it isn't |
| 356 clear what the boolean represents: | 367 clear what the boolean represents: |
| 357 | 368 |
| 358 <div class="bad"> | 369 <div class="bad"> |
| 359 {% prettify dart %} | 370 {% prettify dart %} |
| 360 new Task(true); | 371 new Task(true); |
| 361 new Task(false); | 372 new Task(false); |
| 362 new ListBox(false, true, true); | 373 new ListBox(false, true, true); |
| 363 {% endprettify %} | 374 {% endprettify %} |
| 364 </div> | 375 </div> |
| 365 | 376 |
| 366 Instead, consider using named arguments, named constructors, or named constants | 377 Instead, consider using named arguments, named constructors, or named constants |
| 367 to clarify what the call is doing. | 378 to clarify what the call is doing. |
| 368 | 379 |
| 369 <div class="good"> | 380 <div class="good"> |
| 370 {% prettify dart %} | 381 {% prettify dart %} |
| 371 new Task.oneShot(); | 382 new Task.oneShot(); |
| 372 new Task.repeating(); | 383 new Task.repeating(); |
| 373 new ListBox(scroll: true, showScrollbars: true); | 384 new ListBox(scroll: true, showScrollbars: true); |
| 374 {% endprettify %} | 385 {% endprettify %} |
| 375 </div> | 386 </div> |
| 376 | 387 |
| 377 ## Type annotations | 388 ## Type annotations |
| 378 | 389 |
| 379 #### PREFER providing type annotations on public APIs. | 390 #### PREFER providing type annotations on public APIs. |
| 391 {:.no_toc} |
| 380 | 392 |
| 381 | 393 |
| 382 Type annotations are important documentation for how a library should be used. | 394 Type annotations are important documentation for how a library should be used. |
| 383 Annotating the parameter and return types of public methods and functions helps | 395 Annotating the parameter and return types of public methods and functions helps |
| 384 users understand what the API expects and what it provides. | 396 users understand what the API expects and what it provides. |
| 385 | 397 |
| 386 If, however, a public API does accept any type, or accepts a range of values | 398 If, however, a public API does accept any type, or accepts a range of values |
| 387 that Dart's type system cannot express, then it is acceptable to leave that | 399 that Dart's type system cannot express, then it is acceptable to leave that |
| 388 untyped. | 400 untyped. |
| 389 | 401 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 405 {% prettify dart %} | 417 {% prettify dart %} |
| 406 Future<bool> install(PackageId id, String destPath) { | 418 Future<bool> install(PackageId id, String destPath) { |
| 407 /* ... */ | 419 /* ... */ |
| 408 } | 420 } |
| 409 {% endprettify %} | 421 {% endprettify %} |
| 410 </div> | 422 </div> |
| 411 | 423 |
| 412 With types, all of this is clarified. | 424 With types, all of this is clarified. |
| 413 | 425 |
| 414 #### PREFER using `var` without a type annotation for local variables. | 426 #### PREFER using `var` without a type annotation for local variables. |
| 427 {:.no_toc} |
| 415 | 428 |
| 416 | 429 |
| 417 Method bodies in modern code tend to be short, and the types of local variables | 430 Method bodies in modern code tend to be short, and the types of local variables |
| 418 are almost always trivially inferrable from the initializing expression, so | 431 are almost always trivially inferrable from the initializing expression, so |
| 419 explicit type annotations are usually just visual noise. Decent editors can | 432 explicit type annotations are usually just visual noise. Decent editors can |
| 420 infer the type of local variables and still provide the auto-complete and | 433 infer the type of local variables and still provide the auto-complete and |
| 421 tooling support you expect. | 434 tooling support you expect. |
| 422 | 435 |
| 423 <div class="good"> | 436 <div class="good"> |
| 424 {% prettify dart %} | 437 {% prettify dart %} |
| (...skipping 15 matching lines...) Expand all Loading... |
| 440 for (Person person in people) { | 453 for (Person person in people) { |
| 441 peopleByZip.putIfAbsent(person.zip, () => <Person>[]); | 454 peopleByZip.putIfAbsent(person.zip, () => <Person>[]); |
| 442 peopleByZip[person.zip].add(person); | 455 peopleByZip[person.zip].add(person); |
| 443 } | 456 } |
| 444 return peopleByZip; | 457 return peopleByZip; |
| 445 } | 458 } |
| 446 {% endprettify %} | 459 {% endprettify %} |
| 447 </div> | 460 </div> |
| 448 | 461 |
| 449 #### PREFER using `double` or `int` instead of `num` for parameter type annotati
ons in performance sensitive code. | 462 #### PREFER using `double` or `int` instead of `num` for parameter type annotati
ons in performance sensitive code. |
| 463 {:.no_toc} |
| 450 | 464 |
| 451 Monomorphic call sites (sites that have stable input types) | 465 Monomorphic call sites (sites that have stable input types) |
| 452 can be optimized much easier than polymorphic call sites (sites that have | 466 can be optimized much easier than polymorphic call sites (sites that have |
| 453 varying input types). | 467 varying input types). |
| 454 | 468 |
| 455 Whenever you can, pick a specific number type for your type annotation. | 469 Whenever you can, pick a specific number type for your type annotation. |
| 456 Explicitly say `double` or `int` to help your users pass in a consistent type | 470 Explicitly say `double` or `int` to help your users pass in a consistent type |
| 457 to your function or method. | 471 to your function or method. |
| 458 | 472 |
| 459 When you use `num` as a type annotation, you are saying "either an int or | 473 When you use `num` as a type annotation, you are saying "either an int or |
| 460 a double can go here." This ambiguity it harder for Dart runtimes to optimize. | 474 a double can go here." This ambiguity it harder for Dart runtimes to optimize. |
| 461 | 475 |
| 462 #### DON'T type annotate initializing formals. | 476 #### DON'T type annotate initializing formals. |
| 477 {:.no_toc} |
| 463 | 478 |
| 464 | 479 |
| 465 If a constructor parameter is using `this.` to initialize a field, then the type | 480 If a constructor parameter is using `this.` to initialize a field, then the type |
| 466 of the parameter is understood to be the same type as the field. | 481 of the parameter is understood to be the same type as the field. |
| 467 | 482 |
| 468 <div class="good"> | 483 <div class="good"> |
| 469 {% prettify dart %} | 484 {% prettify dart %} |
| 470 class Point { | 485 class Point { |
| 471 int x, y; | 486 int x, y; |
| 472 Point(this.x, this.y); | 487 Point(this.x, this.y); |
| 473 } | 488 } |
| 474 {% endprettify %} | 489 {% endprettify %} |
| 475 </div> | 490 </div> |
| 476 | 491 |
| 477 <div class="bad"> | 492 <div class="bad"> |
| 478 {% prettify dart %} | 493 {% prettify dart %} |
| 479 class Point { | 494 class Point { |
| 480 int x, y; | 495 int x, y; |
| 481 Point(int this.x, int this.y); | 496 Point(int this.x, int this.y); |
| 482 } | 497 } |
| 483 {% endprettify %} | 498 {% endprettify %} |
| 484 </div> | 499 </div> |
| 485 | 500 |
| 486 #### AVOID annotating types on function expressions. | 501 #### AVOID annotating types on function expressions. |
| 502 {:.no_toc} |
| 487 | 503 |
| 488 | 504 |
| 489 The value of function expressions is their brevity. If a function is complex | 505 The value of function expressions is their brevity. If a function is complex |
| 490 enough that types are needed to understand it, it should probably be a function | 506 enough that types are needed to understand it, it should probably be a function |
| 491 statement or a method. Conversely, if it is short enough to be an expression, it | 507 statement or a method. Conversely, if it is short enough to be an expression, it |
| 492 likely doesn't need types. | 508 likely doesn't need types. |
| 493 | 509 |
| 494 <div class="good"> | 510 <div class="good"> |
| 495 {% prettify dart %} | 511 {% prettify dart %} |
| 496 var names = people.map((person) => person.name); | 512 var names = people.map((person) => person.name); |
| 497 {% endprettify %} | 513 {% endprettify %} |
| 498 </div> | 514 </div> |
| 499 | 515 |
| 500 <div class="bad"> | 516 <div class="bad"> |
| 501 {% prettify dart %} | 517 {% prettify dart %} |
| 502 var names = people.map((Person person) { | 518 var names = people.map((Person person) { |
| 503 return person.name; | 519 return person.name; |
| 504 }); | 520 }); |
| 505 {% endprettify %} | 521 {% endprettify %} |
| 506 </div> | 522 </div> |
| 507 | 523 |
| 508 #### AVOID annotating with `dynamic` when not required. | 524 #### AVOID annotating with `dynamic` when not required. |
| 525 {:.no_toc} |
| 509 | 526 |
| 510 | 527 |
| 511 In most places in Dart, a type annotation can be omitted, in which case the type | 528 In most places in Dart, a type annotation can be omitted, in which case the type |
| 512 will automatically be `dynamic`. Thus, omitting the type annotation entirely is | 529 will automatically be `dynamic`. Thus, omitting the type annotation entirely is |
| 513 semantically equivalent but more terse. | 530 semantically equivalent but more terse. |
| 514 | 531 |
| 515 <div class="good"> | 532 <div class="good"> |
| 516 {% prettify dart %} | 533 {% prettify dart %} |
| 517 lookUpOrDefault(String name, Map map, defaultValue) { | 534 lookUpOrDefault(String name, Map map, defaultValue) { |
| 518 var value = map[name]; | 535 var value = map[name]; |
| 519 if (value != null) return value; | 536 if (value != null) return value; |
| 520 return defaultValue; | 537 return defaultValue; |
| 521 } | 538 } |
| 522 {% endprettify %} | 539 {% endprettify %} |
| 523 </div> | 540 </div> |
| 524 | 541 |
| 525 <div class="bad"> | 542 <div class="bad"> |
| 526 {% prettify dart %} | 543 {% prettify dart %} |
| 527 dynamic lookUpOrDefault(String name, Map map, dynamic defaultValue) { | 544 dynamic lookUpOrDefault(String name, Map map, dynamic defaultValue) { |
| 528 var value = map[name]; | 545 var value = map[name]; |
| 529 if (value != null) return value; | 546 if (value != null) return value; |
| 530 return defaultValue; | 547 return defaultValue; |
| 531 } | 548 } |
| 532 {% endprettify %} | 549 {% endprettify %} |
| 533 </div> | 550 </div> |
| 534 | 551 |
| 535 #### DO annotate with `Object` instead of `dynamic` to indicate any object is ac
cepted. | 552 #### DO annotate with `Object` instead of `dynamic` to indicate any object is ac
cepted. |
| 553 {:.no_toc} |
| 536 | 554 |
| 537 | 555 |
| 538 Some operations will work with any possible object. For example, a log method | 556 Some operations will work with any possible object. For example, a log method |
| 539 could take any object and call `toString()` on it. Two types in Dart permit all | 557 could take any object and call `toString()` on it. Two types in Dart permit all |
| 540 objects: `Object` and `dynamic`. However, they convey two different things. | 558 objects: `Object` and `dynamic`. However, they convey two different things. |
| 541 | 559 |
| 542 The `Object` annotation says "I accept any object, and I only require it to have | 560 The `Object` annotation says "I accept any object, and I only require it to have |
| 543 the methods that `Object` itself defines." | 561 the methods that `Object` itself defines." |
| 544 | 562 |
| 545 A `dynamic` type annotation means that no type annotation can express what | 563 A `dynamic` type annotation means that no type annotation can express what |
| (...skipping 12 matching lines...) Expand all Loading... |
| 558 if (arg is bool) return arg; | 576 if (arg is bool) return arg; |
| 559 if (arg is String) return arg == 'true'; | 577 if (arg is String) return arg == 'true'; |
| 560 throw new ArgumentError('Cannot convert $arg to a bool.'); | 578 throw new ArgumentError('Cannot convert $arg to a bool.'); |
| 561 } | 579 } |
| 562 {% endprettify %} | 580 {% endprettify %} |
| 563 </div> | 581 </div> |
| 564 | 582 |
| 565 ## Names | 583 ## Names |
| 566 | 584 |
| 567 #### DO name types using `UpperCamelCase`. | 585 #### DO name types using `UpperCamelCase`. |
| 586 {:.no_toc} |
| 568 | 587 |
| 569 | 588 |
| 570 Classes and typedefs should capitalize the first letter of each word (including | 589 Classes and typedefs should capitalize the first letter of each word (including |
| 571 the first word), and use no separators. | 590 the first word), and use no separators. |
| 572 | 591 |
| 573 <div class="good" markdown="1"> | 592 <div class="good" markdown="1"> |
| 574 {% prettify dart %} | 593 {% prettify dart %} |
| 575 class SliderMenu { | 594 class SliderMenu { |
| 576 // ... | 595 // ... |
| 577 } | 596 } |
| 578 | 597 |
| 579 class HttpRequest { | 598 class HttpRequest { |
| 580 // ... | 599 // ... |
| 581 } | 600 } |
| 582 | 601 |
| 583 typedef num Adder(num x, num y); | 602 typedef num Adder(num x, num y); |
| 584 {% endprettify %} | 603 {% endprettify %} |
| 585 </div> | 604 </div> |
| 586 | 605 |
| 587 #### DO name constants using `ALL_CAPS_WITH_UNDERSCORES`. | 606 #### DO name constants using `ALL_CAPS_WITH_UNDERSCORES`. |
| 607 {:.no_toc} |
| 588 | 608 |
| 589 | 609 |
| 590 Constants—variables declared using `const`—are special in Dart | 610 Constants—variables declared using `const`—are special in Dart |
| 591 because they can be used in constant expressions, unlike `final` variables. To | 611 because they can be used in constant expressions, unlike `final` variables. To |
| 592 clarify this, they are given their own naming style. | 612 clarify this, they are given their own naming style. |
| 593 | 613 |
| 594 <div class="good"> | 614 <div class="good"> |
| 595 {% prettify dart %} | 615 {% prettify dart %} |
| 596 const PI = 3.14; | 616 const PI = 3.14; |
| 597 const DEFAULT_TIMEOUT = 1000; | 617 const DEFAULT_TIMEOUT = 1000; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 609 const kDefaultTimeout = 1000; | 629 const kDefaultTimeout = 1000; |
| 610 final URL_SCHEME = new RegExp('^([a-z]+):'); | 630 final URL_SCHEME = new RegExp('^([a-z]+):'); |
| 611 | 631 |
| 612 class Dice { | 632 class Dice { |
| 613 static final NUMBER_GENERATOR = new Random(); | 633 static final NUMBER_GENERATOR = new Random(); |
| 614 } | 634 } |
| 615 {% endprettify %} | 635 {% endprettify %} |
| 616 </div> | 636 </div> |
| 617 | 637 |
| 618 #### DO name other identifiers using `lowerCamelCase`. | 638 #### DO name other identifiers using `lowerCamelCase`. |
| 639 {:.no_toc} |
| 619 | 640 |
| 620 | 641 |
| 621 Class members, top-level definitions, variables, parameters, and named | 642 Class members, top-level definitions, variables, parameters, and named |
| 622 parameters should capitalize the first letter of each word *except* the first | 643 parameters should capitalize the first letter of each word *except* the first |
| 623 word, and use no separators. | 644 word, and use no separators. |
| 624 | 645 |
| 625 <div class="good"> | 646 <div class="good"> |
| 626 {% prettify dart %} | 647 {% prettify dart %} |
| 627 var item; | 648 var item; |
| 628 | 649 |
| 629 HttpRequest httpRequest; | 650 HttpRequest httpRequest; |
| 630 | 651 |
| 631 align(clearItems) { | 652 align(clearItems) { |
| 632 // ... | 653 // ... |
| 633 } | 654 } |
| 634 {% endprettify %} | 655 {% endprettify %} |
| 635 </div> | 656 </div> |
| 636 | 657 |
| 637 #### DO name libraries and source files using `lowercase_with_underscores`. | 658 #### DO name libraries and source files using `lowercase_with_underscores`. |
| 659 {:.no_toc} |
| 638 | 660 |
| 639 | 661 |
| 640 Some file systems are not case-sensitive, so many projects require filenames to | 662 Some file systems are not case-sensitive, so many projects require filenames to |
| 641 be all lowercase. Using a separate character allows names to still be readable | 663 be all lowercase. Using a separate character allows names to still be readable |
| 642 in that form. Using underscores as the separator ensures that the name is still | 664 in that form. Using underscores as the separator ensures that the name is still |
| 643 a valid Dart identifier, which may be helpful if the language later supports | 665 a valid Dart identifier, which may be helpful if the language later supports |
| 644 symbolic imports. | 666 symbolic imports. |
| 645 | 667 |
| 646 <div class="good" markdown="1"> | 668 <div class="good" markdown="1"> |
| 647 Good: | 669 Good: |
| 648 | 670 |
| 649 * `slider_menu.dart` | 671 * `slider_menu.dart` |
| 650 * `file_system.dart` | 672 * `file_system.dart` |
| 651 * `library peg_parser;` | 673 * `library peg_parser;` |
| 652 </div> | 674 </div> |
| 653 | 675 |
| 654 <div class="bad" markdown="1"> | 676 <div class="bad" markdown="1"> |
| 655 Bad: | 677 Bad: |
| 656 | 678 |
| 657 * `SliderMenu.dart` | 679 * `SliderMenu.dart` |
| 658 * `filesystem.dart` | 680 * `filesystem.dart` |
| 659 * `library peg-parser;` | 681 * `library peg-parser;` |
| 660 </div> | 682 </div> |
| 661 | 683 |
| 662 #### DO capitalize acronyms and abbreviations longer than two letters like words
. | 684 #### DO capitalize acronyms and abbreviations longer than two letters like words
. |
| 685 {:.no_toc} |
| 663 | 686 |
| 664 | 687 |
| 665 Capitalized acronyms can be harder to read, and are ambiguous when you have | 688 Capitalized acronyms can be harder to read, and are ambiguous when you have |
| 666 multiple adjacent acronyms. Given the name `HTTPSFTPConnection`, there's no way | 689 multiple adjacent acronyms. Given the name `HTTPSFTPConnection`, there's no way |
| 667 to tell if that's an HTTPS FTP connection or an HTTP SFTP one. | 690 to tell if that's an HTTPS FTP connection or an HTTP SFTP one. |
| 668 | 691 |
| 669 To avoid this, acronyms are capitalized like regular words, except for | 692 To avoid this, acronyms are capitalized like regular words, except for |
| 670 two-letter ones. | 693 two-letter ones. |
| 671 | 694 |
| 672 <div class="good"> | 695 <div class="good"> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 686 UiHandler | 709 UiHandler |
| 687 IoStream | 710 IoStream |
| 688 HTTPRequest | 711 HTTPRequest |
| 689 Id | 712 Id |
| 690 {% endprettify %} | 713 {% endprettify %} |
| 691 </div> | 714 </div> |
| 692 | 715 |
| 693 ## Comments | 716 ## Comments |
| 694 | 717 |
| 695 #### DO comment members and types using doc-style comments. | 718 #### DO comment members and types using doc-style comments. |
| 719 {:.no_toc} |
| 696 | 720 |
| 697 | 721 |
| 698 Dart supports two syntaxes of doc comments. Line doc comments start each line | 722 Dart supports two syntaxes of doc comments. Line doc comments start each line |
| 699 with `///`: | 723 with `///`: |
| 700 | 724 |
| 701 <div class="good"> | 725 <div class="good"> |
| 702 {% prettify dart %} | 726 {% prettify dart %} |
| 703 /// Parses a set of option strings. For each option: | 727 /// Parses a set of option strings. For each option: |
| 704 /// | 728 /// |
| 705 /// * If it is `null`, then it is ignored. | 729 /// * If it is `null`, then it is ignored. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 722 // ... | 746 // ... |
| 723 } | 747 } |
| 724 {% endprettify %} | 748 {% endprettify %} |
| 725 </div> | 749 </div> |
| 726 | 750 |
| 727 Within a doc comment, you can use [markdown][] for formatting. | 751 Within a doc comment, you can use [markdown][] for formatting. |
| 728 | 752 |
| 729 [markdown]: http://daringfireball.net/projects/markdown/ | 753 [markdown]: http://daringfireball.net/projects/markdown/ |
| 730 | 754 |
| 731 #### DO use line comments for everything else. | 755 #### DO use line comments for everything else. |
| 756 {:.no_toc} |
| 732 | 757 |
| 733 | 758 |
| 734 <div class="good"> | 759 <div class="good"> |
| 735 {% prettify dart %} | 760 {% prettify dart %} |
| 736 greet(name) { | 761 greet(name) { |
| 737 // Assume we have a valid name. | 762 // Assume we have a valid name. |
| 738 print('Hi, $name!'); | 763 print('Hi, $name!'); |
| 739 } | 764 } |
| 740 {% endprettify %} | 765 {% endprettify %} |
| 741 </div> | 766 </div> |
| 742 | 767 |
| 743 <div class="bad"> | 768 <div class="bad"> |
| 744 {% prettify dart %} | 769 {% prettify dart %} |
| 745 greet(name) { | 770 greet(name) { |
| 746 /* Assume we have a valid name. */ | 771 /* Assume we have a valid name. */ |
| 747 print('Hi, $name!'); | 772 print('Hi, $name!'); |
| 748 } | 773 } |
| 749 {% endprettify %} | 774 {% endprettify %} |
| 750 </div> | 775 </div> |
| 751 | 776 |
| 752 #### DO capitalize and punctuate comments like sentences. | 777 #### DO capitalize and punctuate comments like sentences. |
| 778 {:.no_toc} |
| 753 | 779 |
| 754 | 780 |
| 755 This doesn't mean that the comment must always be a complete sentence, though it | 781 This doesn't mean that the comment must always be a complete sentence, though it |
| 756 usually should. "Returns the number of items." is an acceptable comment. | 782 usually should. "Returns the number of items." is an acceptable comment. |
| 757 | 783 |
| 758 <div class="good"> | 784 <div class="good"> |
| 759 {% prettify dart %} | 785 {% prettify dart %} |
| 760 // Remove the last item from the collection. | 786 // Remove the last item from the collection. |
| 761 {% endprettify %} | 787 {% endprettify %} |
| 762 </div> | 788 </div> |
| 763 | 789 |
| 764 <div class="bad"> | 790 <div class="bad"> |
| 765 {% prettify dart %} | 791 {% prettify dart %} |
| 766 // remove the last item from the collection | 792 // remove the last item from the collection |
| 767 {% endprettify %} | 793 {% endprettify %} |
| 768 </div> | 794 </div> |
| 769 | 795 |
| 770 #### DO use square brackets in doc comments for identifiers that are in scope. | 796 #### DO use square brackets in doc comments for identifiers that are in scope. |
| 797 {:.no_toc} |
| 771 | 798 |
| 772 | 799 |
| 773 If you surround things like variable, method or type names in square brackets, | 800 If you surround things like variable, method or type names in square brackets, |
| 774 then documentation generators can look up the name and cross-link the two | 801 then documentation generators can look up the name and cross-link the two |
| 775 together. | 802 together. |
| 776 | 803 |
| 777 <div class="good"> | 804 <div class="good"> |
| 778 {% prettify dart %} | 805 {% prettify dart %} |
| 779 import 'dart:math'; | 806 import 'dart:math'; |
| 780 | 807 |
| 781 /// Rolls both [Dice] and returns the highest rolled value. | 808 /// Rolls both [Dice] and returns the highest rolled value. |
| 782 num greatestRoll(Dice a, Dice b) => max(a.roll(), b.roll()); | 809 num greatestRoll(Dice a, Dice b) => max(a.roll(), b.roll()); |
| 783 {% endprettify %} | 810 {% endprettify %} |
| 784 </div> | 811 </div> |
| 785 | 812 |
| 786 #### DO describe method signatures in the prose of the documentation comment. | 813 #### DO describe method signatures in the prose of the documentation comment. |
| 814 {:.no_toc} |
| 787 | 815 |
| 788 | 816 |
| 789 | 817 |
| 790 Other languages use verbose tags and sections to describe what the parameters | 818 Other languages use verbose tags and sections to describe what the parameters |
| 791 and returns of a method are. | 819 and returns of a method are. |
| 792 | 820 |
| 793 <div class="bad"> | 821 <div class="bad"> |
| 794 {% prettify dart %} | 822 {% prettify dart %} |
| 795 /** | 823 /** |
| 796 * Defines a flag with the given name and abbreviation. | 824 * Defines a flag with the given name and abbreviation. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 823 {% endprettify %} | 851 {% endprettify %} |
| 824 </div> | 852 </div> |
| 825 | 853 |
| 826 ## Whitespace | 854 ## Whitespace |
| 827 | 855 |
| 828 Like many languages, Dart ignores whitespace. However, *humans* don't. Having a | 856 Like many languages, Dart ignores whitespace. However, *humans* don't. Having a |
| 829 consistent whitespace style helps ensure that human readers see code the same | 857 consistent whitespace style helps ensure that human readers see code the same |
| 830 way the compiler does. | 858 way the compiler does. |
| 831 | 859 |
| 832 #### DON'T use tabs. | 860 #### DON'T use tabs. |
| 861 {:.no_toc} |
| 833 | 862 |
| 834 | 863 |
| 835 Using spaces for formatting ensures the code looks the same in everyone's | 864 Using spaces for formatting ensures the code looks the same in everyone's |
| 836 editor. It also makes sure it looks the same when posted to blogs, or on code | 865 editor. It also makes sure it looks the same when posted to blogs, or on code |
| 837 sites like [Google Code][] or [GitHub][]. | 866 sites like [Google Code][] or [GitHub][]. |
| 838 | 867 |
| 839 [google code]: http://code.google.com/projecthosting/ | 868 [google code]: http://code.google.com/projecthosting/ |
| 840 [github]: http://github.com | 869 [github]: http://github.com |
| 841 | 870 |
| 842 Modern editors emulate the behavior of tabs while inserting spaces, giving you | 871 Modern editors emulate the behavior of tabs while inserting spaces, giving you |
| 843 the easy editing of tabs and the consistency of spaces. | 872 the easy editing of tabs and the consistency of spaces. |
| 844 | 873 |
| 845 #### AVOID lines longer than 80 characters. | 874 #### AVOID lines longer than 80 characters. |
| 875 {:.no_toc} |
| 846 | 876 |
| 847 | 877 |
| 848 Readability studies show that long lines of text are harder to read because your | 878 Readability studies show that long lines of text are harder to read because your |
| 849 eye has to travel farther when moving to the beginning of the next line. This is | 879 eye has to travel farther when moving to the beginning of the next line. This is |
| 850 why newspapers and magazines use multiple columns of text. | 880 why newspapers and magazines use multiple columns of text. |
| 851 | 881 |
| 852 If you really find yourself wanting lines longer than 80 characters, our | 882 If you really find yourself wanting lines longer than 80 characters, our |
| 853 experience is that your code is likely too verbose and could be a little more | 883 experience is that your code is likely too verbose and could be a little more |
| 854 compact. Do you really need to call that class | 884 compact. Do you really need to call that class |
| 855 `AbstractWidgetFactoryManagerBuilder`? | 885 `AbstractWidgetFactoryManagerBuilder`? |
| 856 | 886 |
| 857 #### DO place the operator on the preceding line in a multi-line expression. | 887 #### DO place the operator on the preceding line in a multi-line expression. |
| 888 {:.no_toc} |
| 858 | 889 |
| 859 | 890 |
| 860 There are valid arguments for both styles but most of our code seems to go this | 891 There are valid arguments for both styles but most of our code seems to go this |
| 861 way, and consistency matters most. | 892 way, and consistency matters most. |
| 862 | 893 |
| 863 <div class="good"> | 894 <div class="good"> |
| 864 {% prettify dart %} | 895 {% prettify dart %} |
| 865 if (isDeepFried || | 896 if (isDeepFried || |
| 866 (hasPieCrust && !vegan) || | 897 (hasPieCrust && !vegan) || |
| 867 containsBacon) { | 898 containsBacon) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 880 </div> | 911 </div> |
| 881 | 912 |
| 882 <div class="bad"> | 913 <div class="bad"> |
| 883 {% prettify dart %} | 914 {% prettify dart %} |
| 884 bobLikes() | 915 bobLikes() |
| 885 => isDeepFried || (hasPieCrust && !vegan) || containsBacon; | 916 => isDeepFried || (hasPieCrust && !vegan) || containsBacon; |
| 886 {% endprettify %} | 917 {% endprettify %} |
| 887 </div> | 918 </div> |
| 888 | 919 |
| 889 #### DO place the `.` on the next line in a multi-line expression. | 920 #### DO place the `.` on the next line in a multi-line expression. |
| 921 {:.no_toc} |
| 890 | 922 |
| 891 | 923 |
| 892 This supercedes the previous rule. Unlike other operators, if you split an | 924 This supercedes the previous rule. Unlike other operators, if you split an |
| 893 expression on a `.`, then put that at the beginning of the second line. | 925 expression on a `.`, then put that at the beginning of the second line. |
| 894 | 926 |
| 895 <div class="good"> | 927 <div class="good"> |
| 896 {% prettify dart %} | 928 {% prettify dart %} |
| 897 someVeryLongVariable.withAVeryLongProperty | 929 someVeryLongVariable.withAVeryLongProperty |
| 898 .aMethodOnThatObject(); | 930 .aMethodOnThatObject(); |
| 899 {% endprettify %} | 931 {% endprettify %} |
| 900 </div> | 932 </div> |
| 901 | 933 |
| 902 #### DO indent block bodies two spaces. | 934 #### DO indent block bodies two spaces. |
| 935 {:.no_toc} |
| 903 | 936 |
| 904 | 937 |
| 905 <div class="good"> | 938 <div class="good"> |
| 906 {% prettify dart %} | 939 {% prettify dart %} |
| 907 if (condition) { | 940 if (condition) { |
| 908 print('hi'); | 941 print('hi'); |
| 909 } | 942 } |
| 910 {% endprettify %} | 943 {% endprettify %} |
| 911 </div> | 944 </div> |
| 912 | 945 |
| 913 #### DO indent continued lines with at least four spaces. | 946 #### DO indent continued lines with at least four spaces. |
| 947 {:.no_toc} |
| 914 | 948 |
| 915 | 949 |
| 916 <div class="good"> | 950 <div class="good"> |
| 917 {% prettify dart %} | 951 {% prettify dart %} |
| 918 someLongObject.aReallyLongMethodName(longArg, anotherLongArg, | 952 someLongObject.aReallyLongMethodName(longArg, anotherLongArg, |
| 919 wrappedToNextLine); | 953 wrappedToNextLine); |
| 920 {% endprettify %} | 954 {% endprettify %} |
| 921 </div> | 955 </div> |
| 922 | 956 |
| 923 You may indent more than four spaces to line things up if you like: | 957 You may indent more than four spaces to line things up if you like: |
| 924 | 958 |
| 925 <div class="good"> | 959 <div class="good"> |
| 926 {% prettify dart %} | 960 {% prettify dart %} |
| 927 someLongObject.aReallyLongMethodName(longArg, anotherLongArg, | 961 someLongObject.aReallyLongMethodName(longArg, anotherLongArg, |
| 928 wrappedToNextLine); | 962 wrappedToNextLine); |
| 929 {% endprettify %} | 963 {% endprettify %} |
| 930 </div> | 964 </div> |
| 931 | 965 |
| 932 #### DON'T indent lines that are continued with a function expression. | 966 #### DON'T indent lines that are continued with a function expression. |
| 967 {:.no_toc} |
| 933 | 968 |
| 934 | 969 |
| 935 The one exception to the above rule is function expressions used within larger | 970 The one exception to the above rule is function expressions used within larger |
| 936 expressions, like being passed to methods. These are formatted like so: | 971 expressions, like being passed to methods. These are formatted like so: |
| 937 | 972 |
| 938 <div class="good"> | 973 <div class="good"> |
| 939 {% prettify dart %} | 974 {% prettify dart %} |
| 940 new Future.delayed(const Duration(seconds: 1), () { | 975 new Future.delayed(const Duration(seconds: 1), () { |
| 941 print('I am a callback'); | 976 print('I am a callback'); |
| 942 }); | 977 }); |
| 943 {% endprettify %} | 978 {% endprettify %} |
| 944 </div> | 979 </div> |
| 945 | 980 |
| 946 <div class="bad"> | 981 <div class="bad"> |
| 947 {% prettify dart %} | 982 {% prettify dart %} |
| 948 new Future.delayed(const Duration(seconds: 1), () { | 983 new Future.delayed(const Duration(seconds: 1), () { |
| 949 print('I am a callback'); | 984 print('I am a callback'); |
| 950 }); | 985 }); |
| 951 {% endprettify %} | 986 {% endprettify %} |
| 952 </div> | 987 </div> |
| 953 | 988 |
| 954 #### DO place the opening curly brace (`{`) on the same line as what it follows. | 989 #### DO place the opening curly brace (`{`) on the same line as what it follows. |
| 990 {:.no_toc} |
| 955 | 991 |
| 956 | 992 |
| 957 <div class="good"> | 993 <div class="good"> |
| 958 {% prettify dart %} | 994 {% prettify dart %} |
| 959 class Foo { | 995 class Foo { |
| 960 method() { | 996 method() { |
| 961 if (true) { | 997 if (true) { |
| 962 // ... | 998 // ... |
| 963 } else { | 999 } else { |
| 964 // ... | 1000 // ... |
| 965 } | 1001 } |
| 966 } | 1002 } |
| 967 } | 1003 } |
| 968 {% endprettify %} | 1004 {% endprettify %} |
| 969 </div> | 1005 </div> |
| 970 | 1006 |
| 971 #### DO use curly braces for all flow control structures. | 1007 #### DO use curly braces for all flow control structures. |
| 1008 {:.no_toc} |
| 972 | 1009 |
| 973 | 1010 |
| 974 Doing so avoids the [dangling else][] problem. | 1011 Doing so avoids the [dangling else][] problem. |
| 975 | 1012 |
| 976 [dangling else]: http://en.wikipedia.org/wiki/Dangling_else | 1013 [dangling else]: http://en.wikipedia.org/wiki/Dangling_else |
| 977 | 1014 |
| 978 <div class="good"> | 1015 <div class="good"> |
| 979 {% prettify dart %} | 1016 {% prettify dart %} |
| 980 if (true) { | 1017 if (true) { |
| 981 print('sanity'); | 1018 print('sanity'); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 996 There is one exception to this: short `if` statements with no `else` clause that | 1033 There is one exception to this: short `if` statements with no `else` clause that |
| 997 fit on one line may omit the braces. | 1034 fit on one line may omit the braces. |
| 998 | 1035 |
| 999 <div class="good"> | 1036 <div class="good"> |
| 1000 {% prettify dart %} | 1037 {% prettify dart %} |
| 1001 if (arg == null) return defaultValue; | 1038 if (arg == null) return defaultValue; |
| 1002 {% endprettify %} | 1039 {% endprettify %} |
| 1003 </div> | 1040 </div> |
| 1004 | 1041 |
| 1005 #### DO indent switch cases two spaces and case bodies four spaces. | 1042 #### DO indent switch cases two spaces and case bodies four spaces. |
| 1043 {:.no_toc} |
| 1006 | 1044 |
| 1007 | 1045 |
| 1008 <div class="good"> | 1046 <div class="good"> |
| 1009 {% prettify dart %} | 1047 {% prettify dart %} |
| 1010 switch (fruit) { | 1048 switch (fruit) { |
| 1011 case 'apple': | 1049 case 'apple': |
| 1012 print('delish'); | 1050 print('delish'); |
| 1013 break; | 1051 break; |
| 1014 | 1052 |
| 1015 case 'durian': | 1053 case 'durian': |
| 1016 print('stinky'); | 1054 print('stinky'); |
| 1017 break; | 1055 break; |
| 1018 } | 1056 } |
| 1019 {% endprettify %} | 1057 {% endprettify %} |
| 1020 </div> | 1058 </div> |
| 1021 | 1059 |
| 1022 #### DO use spaces around binary and ternary operators, after commas, and not ar
ound unary operators. | 1060 #### DO use spaces around binary and ternary operators, after commas, and not ar
ound unary operators. |
| 1061 {:.no_toc} |
| 1023 | 1062 |
| 1024 | 1063 |
| 1025 | 1064 |
| 1026 Note that `<` and `>` are considered binary operators when used as expressions, | 1065 Note that `<` and `>` are considered binary operators when used as expressions, |
| 1027 but not for specifying generic types. Both `is` and `is!` are considered single | 1066 but not for specifying generic types. Both `is` and `is!` are considered single |
| 1028 binary operators. However, the `.` used to access members is not and should | 1067 binary operators. However, the `.` used to access members is not and should |
| 1029 *not* have spaces around it. | 1068 *not* have spaces around it. |
| 1030 | 1069 |
| 1031 <div class="good"> | 1070 <div class="good"> |
| 1032 {% prettify dart %} | 1071 {% prettify dart %} |
| 1033 a = 1 + 2 / (3 * -b); | 1072 a = 1 + 2 / (3 * -b); |
| 1034 c = !condition == a > b; | 1073 c = !condition == a > b; |
| 1035 d = condition ? b : object.method(a, b, c); | 1074 d = condition ? b : object.method(a, b, c); |
| 1036 if (obj is! SomeType) print('not SomeType'); | 1075 if (obj is! SomeType) print('not SomeType'); |
| 1037 {% endprettify %} | 1076 {% endprettify %} |
| 1038 </div> | 1077 </div> |
| 1039 | 1078 |
| 1040 <div class="bad"> | 1079 <div class="bad"> |
| 1041 {% prettify dart %} | 1080 {% prettify dart %} |
| 1042 a=1+2/(3* - b); | 1081 a=1+2/(3* - b); |
| 1043 c= ! condition==a>b; | 1082 c= ! condition==a>b; |
| 1044 d= condition?b:object.method(a,b,c); | 1083 d= condition?b:object.method(a,b,c); |
| 1045 if (obj is !SomeType) print('not SomeType'); | 1084 if (obj is !SomeType) print('not SomeType'); |
| 1046 {% endprettify %} | 1085 {% endprettify %} |
| 1047 </div> | 1086 </div> |
| 1048 | 1087 |
| 1049 #### DO place spaces around `in`, and after each `;` in a loop. | 1088 #### DO place spaces around `in`, and after each `;` in a loop. |
| 1089 {:.no_toc} |
| 1050 | 1090 |
| 1051 | 1091 |
| 1052 <div class="good"> | 1092 <div class="good"> |
| 1053 {% prettify dart %} | 1093 {% prettify dart %} |
| 1054 for (var i = 0; i < 100; i++) { | 1094 for (var i = 0; i < 100; i++) { |
| 1055 // ... | 1095 // ... |
| 1056 } | 1096 } |
| 1057 | 1097 |
| 1058 for (final item in collection) { | 1098 for (final item in collection) { |
| 1059 // ... | 1099 // ... |
| 1060 } | 1100 } |
| 1061 {% endprettify %} | 1101 {% endprettify %} |
| 1062 </div> | 1102 </div> |
| 1063 | 1103 |
| 1064 #### DO use a space after flow-control keywords. | 1104 #### DO use a space after flow-control keywords. |
| 1105 {:.no_toc} |
| 1065 | 1106 |
| 1066 | 1107 |
| 1067 This is unlike function and method calls, which do *not* have a space between | 1108 This is unlike function and method calls, which do *not* have a space between |
| 1068 the name and the opening parenthesis. | 1109 the name and the opening parenthesis. |
| 1069 | 1110 |
| 1070 <div class="good"> | 1111 <div class="good"> |
| 1071 {% prettify dart %} | 1112 {% prettify dart %} |
| 1072 while (foo) { | 1113 while (foo) { |
| 1073 // ... | 1114 // ... |
| 1074 } | 1115 } |
| 1075 | 1116 |
| 1076 try { | 1117 try { |
| 1077 // ... | 1118 // ... |
| 1078 } catch (e) { | 1119 } catch (e) { |
| 1079 // ... | 1120 // ... |
| 1080 } | 1121 } |
| 1081 {% endprettify %} | 1122 {% endprettify %} |
| 1082 </div> | 1123 </div> |
| 1083 | 1124 |
| 1084 #### DON'T use a space after `(`, `[`, and `{`, or before `)`, `]`, and `}`. | 1125 #### DON'T use a space after `(`, `[`, and `{`, or before `)`, `]`, and `}`. |
| 1126 {:.no_toc} |
| 1085 | 1127 |
| 1086 | 1128 |
| 1087 Also, do not use a space when using `<` and `>` for generic types. | 1129 Also, do not use a space when using `<` and `>` for generic types. |
| 1088 | 1130 |
| 1089 <div class="good"> | 1131 <div class="good"> |
| 1090 {% prettify dart %} | 1132 {% prettify dart %} |
| 1091 var numbers = <int>[1, 2, (3 + 4)]; | 1133 var numbers = <int>[1, 2, (3 + 4)]; |
| 1092 {% endprettify %} | 1134 {% endprettify %} |
| 1093 </div> | 1135 </div> |
| 1094 | 1136 |
| 1095 #### DO use a space before `{` in function and method bodies. | 1137 #### DO use a space before `{` in function and method bodies. |
| 1138 {:.no_toc} |
| 1096 | 1139 |
| 1097 | 1140 |
| 1098 This is an exception to the above rule. When a `{` is used after a parameter | 1141 This is an exception to the above rule. When a `{` is used after a parameter |
| 1099 list in a function or method, there should be a space between it and the `)` | 1142 list in a function or method, there should be a space between it and the `)` |
| 1100 ending the parameters. | 1143 ending the parameters. |
| 1101 | 1144 |
| 1102 <div class="good"> | 1145 <div class="good"> |
| 1103 {% prettify dart %} | 1146 {% prettify dart %} |
| 1104 getEmptyFn(a) { | 1147 getEmptyFn(a) { |
| 1105 return () {}; | 1148 return () {}; |
| 1106 } | 1149 } |
| 1107 {% endprettify %} | 1150 {% endprettify %} |
| 1108 </div> | 1151 </div> |
| 1109 | 1152 |
| 1110 <div class="bad"> | 1153 <div class="bad"> |
| 1111 {% prettify dart %} | 1154 {% prettify dart %} |
| 1112 getEmptyFn(a){ | 1155 getEmptyFn(a){ |
| 1113 return (){}; | 1156 return (){}; |
| 1114 } | 1157 } |
| 1115 {% endprettify %} | 1158 {% endprettify %} |
| 1116 </div> | 1159 </div> |
| 1117 | 1160 |
| 1118 #### DO format constructor initialization lists with each field on its own line. | 1161 #### DO format constructor initialization lists with each field on its own line. |
| 1162 {:.no_toc} |
| 1119 | 1163 |
| 1120 | 1164 |
| 1121 <div class="good"> | 1165 <div class="good"> |
| 1122 {% prettify dart %} | 1166 {% prettify dart %} |
| 1123 MyClass() | 1167 MyClass() |
| 1124 : firstField = "some value", | 1168 : firstField = "some value", |
| 1125 secondField = "another", | 1169 secondField = "another", |
| 1126 thirdField = "last" { | 1170 thirdField = "last" { |
| 1127 // ... | 1171 // ... |
| 1128 } | 1172 } |
| 1129 {% endprettify %} | 1173 {% endprettify %} |
| 1130 </div> | 1174 </div> |
| 1131 | 1175 |
| 1132 Note that the `:` should be wrapped to the next line and indented four spaces. | 1176 Note that the `:` should be wrapped to the next line and indented four spaces. |
| 1133 Fields should all line up (so all but the first field end up indented six | 1177 Fields should all line up (so all but the first field end up indented six |
| 1134 spaces). | 1178 spaces). |
| 1135 | 1179 |
| 1136 #### DO use a space after `:` in named parameters and named arguments. | 1180 #### DO use a space after `:` in named parameters and named arguments. |
| 1181 {:.no_toc} |
| 1137 | 1182 |
| 1138 | 1183 |
| 1139 <div class="good"> | 1184 <div class="good"> |
| 1140 {% prettify dart %} | 1185 {% prettify dart %} |
| 1141 class ListBox { | 1186 class ListBox { |
| 1142 bool showScrollbars; | 1187 bool showScrollbars; |
| 1143 | 1188 |
| 1144 ListBox({this.showScrollbars: false}); | 1189 ListBox({this.showScrollbars: false}); |
| 1145 } | 1190 } |
| 1146 | 1191 |
| 1147 main() { | 1192 main() { |
| 1148 new ListBox(showScrollbars: true); | 1193 new ListBox(showScrollbars: true); |
| 1149 } | 1194 } |
| 1150 {% endprettify %} | 1195 {% endprettify %} |
| 1151 </div> | 1196 </div> |
| 1152 | 1197 |
| 1153 <div class="bad"> | 1198 <div class="bad"> |
| 1154 {% prettify dart %} | 1199 {% prettify dart %} |
| 1155 new ListBox(showScrollbars:true); | 1200 new ListBox(showScrollbars:true); |
| 1156 new ListBox(showScrollbars : true); | 1201 new ListBox(showScrollbars : true); |
| 1157 {% endprettify %} | 1202 {% endprettify %} |
| 1158 </div> | 1203 </div> |
| 1159 | 1204 |
| 1160 #### DO use a spaces around `=` in optional positional parameters. | 1205 #### DO use a spaces around `=` in optional positional parameters. |
| 1206 {:.no_toc} |
| 1161 | 1207 |
| 1162 | 1208 |
| 1163 <div class="good"> | 1209 <div class="good"> |
| 1164 {% prettify dart %} | 1210 {% prettify dart %} |
| 1165 class HttpServer { | 1211 class HttpServer { |
| 1166 static Future<HttpServer> listen([int port = 80]) { | 1212 static Future<HttpServer> listen([int port = 80]) { |
| 1167 // ... | 1213 // ... |
| 1168 } | 1214 } |
| 1169 } | 1215 } |
| 1170 {% endprettify %} | 1216 {% endprettify %} |
| 1171 </div> | 1217 </div> |
| 1172 | 1218 |
| 1173 <div class="bad"> | 1219 <div class="bad"> |
| 1174 {% prettify dart %} | 1220 {% prettify dart %} |
| 1175 import 'dart:async'; | 1221 import 'dart:async'; |
| 1176 | 1222 |
| 1177 class HttpServer { | 1223 class HttpServer { |
| 1178 static Future<HttpServer> listen([int port=80]) { | 1224 static Future<HttpServer> listen([int port=80]) { |
| 1179 // ... | 1225 // ... |
| 1180 } | 1226 } |
| 1181 } | 1227 } |
| 1182 {% endprettify %} | 1228 {% endprettify %} |
| 1183 </div> | 1229 </div> |
| 1184 | 1230 |
| 1185 #### DO use four spaces for method cascades | 1231 #### DO use four spaces for method cascades |
| 1232 {:.no_toc} |
| 1186 | 1233 |
| 1187 | 1234 |
| 1188 <div class="good"> | 1235 <div class="good"> |
| 1189 {% prettify dart %} | 1236 {% prettify dart %} |
| 1190 var list = new List() | 1237 var list = new List() |
| 1191 ..addAll([1,2,3]) | 1238 ..addAll([1,2,3]) |
| 1192 ..addAll([4,5,6]); | 1239 ..addAll([4,5,6]); |
| 1193 {% endprettify %} | 1240 {% endprettify %} |
| 1194 </div> | 1241 </div> |
| 1195 | 1242 |
| 1196 <div class="bad"> | 1243 <div class="bad"> |
| 1197 {% prettify dart %} | 1244 {% prettify dart %} |
| 1198 var list = new List() | 1245 var list = new List() |
| 1199 ..addAll([1,2,3]) | 1246 ..addAll([1,2,3]) |
| 1200 ..addAll([4,5,6]); | 1247 ..addAll([4,5,6]); |
| 1201 {% endprettify %} | 1248 {% endprettify %} |
| 1202 </div> | 1249 </div> |
| OLD | NEW |