From b408d36b4f5e73ea75441fb9791b849b0a40f58b Mon Sep 17 00:00:00 2001 From: Cal Stephens Date: Tue, 8 Aug 2023 08:40:14 -0700 Subject: [PATCH] =?UTF-8?q?Add=20rule=20to=20prefer=20for=20loops=20over?= =?UTF-8?q?=20functional=20`forEach(=E2=80=A6)`=20method=20(#234)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 38 +++++++++++++++++++ .../AirbnbSwiftFormatTool/airbnb.swiftformat | 2 + 2 files changed, 40 insertions(+) diff --git a/README.md b/README.md index 40d21f0..0598c87 100644 --- a/README.md +++ b/README.md @@ -1239,6 +1239,40 @@ _You can enable the following settings in Xcode by running [this script](resourc +* (link) **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) + +
+ + #### 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() } + ``` + +
+ * (link) **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)
@@ -1564,6 +1598,8 @@ _You can enable the following settings in Xcode by running [this script](resourc } ``` +
+ * (link) **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)
@@ -1584,6 +1620,8 @@ _You can enable the following settings in Xcode by running [this script](resourc planets.first { $0.isGasGiant } ``` +
+ ### Operators * (link) **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) diff --git a/Sources/AirbnbSwiftFormatTool/airbnb.swiftformat b/Sources/AirbnbSwiftFormatTool/airbnb.swiftformat index 9586355..b52546f 100644 --- a/Sources/AirbnbSwiftFormatTool/airbnb.swiftformat +++ b/Sources/AirbnbSwiftFormatTool/airbnb.swiftformat @@ -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