Skip to content

Commit

Permalink
Add rule to prefer for loops over functional forEach(…) method (#234)
Browse files Browse the repository at this point in the history
calda authored Aug 8, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 741e55b commit b408d36
Showing 2 changed files with 40 additions and 0 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1239,6 +1239,40 @@ _You can enable the following settings in Xcode by running [this script](resourc

</details>

* <a id='prefer-for-loop-over-forEach'></a>(<a href='#prefer-for-loop-over-forEach'>link</a>) **Prefer using `for` loops over the functional `forEach()` method**, unless using `forEach()` as the last element in a functional chain. [![SwiftFormat: forLoop](https://img.shields.io/badge/SwiftFormat-forLoop-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#forLoop)

<details>

#### Why?
For loops are more idiomatic than the `forEach()` method, and are typically familiar to all developers who have experience with C-family languages.

For loops are also more expressive than the `forEach()` method. For loops support the `return`, `continue`, and `break` control flow keywords, while `forEach()` only supports `return` (which has the same behavior as `continue` in a for loop).

```swift
// WRONG
planets.forEach { planet in
planet.terraform()
}

// WRONG
planets.forEach {
$0.terraform()
}

// RIGHT
for planet in planets {
planet.terraform()
}

// ALSO FINE, since forEach is useful when paired with other functional methods in a chain.
planets
.filter { !$0.isGasGiant }
.map { PlanetTerraformer(planet: $0) }
.forEach { $0.terraform() }
```

</details>

* <a id='omit-internal-keyword'></a>(<a href='#omit-internal-keyword'>link</a>) **Omit the `internal` keyword** when defining types, properties, or functions with an internal access control level. [![SwiftFormat: redundantInternal](https://img.shields.io/badge/SwiftFormat-redundantInternal-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#redundantInternal)

<details>
@@ -1564,6 +1598,8 @@ _You can enable the following settings in Xcode by running [this script](resourc
}
```

</details>

* <a id='anonymous-trailing-closures'></a>(<a href='#anonymous-trailing-closures'>link</a>) **Prefer trailing closure syntax for closure arguments with no parameter name.** [![SwiftFormat: trailingClosures](https://img.shields.io/badge/SwiftFormat-trailingClosures-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#trailingClosures)

<details>
@@ -1584,6 +1620,8 @@ _You can enable the following settings in Xcode by running [this script](resourc
planets.first { $0.isGasGiant }
```

</details>

### Operators

* <a id='infix-operator-spacing'></a>(<a href='#infix-operator-spacing'>link</a>) **Infix operators should have a single space on either side.** Prefer parenthesis to visually group statements with many operators rather than varying widths of whitespace. This rule does not apply to range operators (e.g. `1...3`) and postfix or prefix operators (e.g. `guest?` or `-1`). [![SwiftLint: operator_usage_whitespace](https://img.shields.io/badge/SwiftLint-operator__usage__whitespace-007A87.svg)](https://realm.github.io/SwiftLint/operator_usage_whitespace)
2 changes: 2 additions & 0 deletions Sources/AirbnbSwiftFormatTool/airbnb.swiftformat
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
--someAny disabled # opaqueGenericParameters
--elseposition same-line #elseOnSameLine
--guardelse next-line #elseOnSameLine
--oneLineForEach wrap #forLoop

# We recommend a max width of 100 but _strictly enforce_ a max width of 130
--maxwidth 130 # wrap
@@ -89,3 +90,4 @@
--rules trailingClosures
--rules elseOnSameLine
--rules sortTypealiases
--rules forLoop

0 comments on commit b408d36

Please sign in to comment.