I'm reading Erica Sadun's Swift Style and rethinking the way I'm structuring my code. This is an ongoing project, so it might be often changed.
type | limit |
---|---|
function | 40 rows |
function | 5 parameters |
file | 400 rows |
file | 120 columns |
Use tabs
Add type only if it's explicitly required by the compiler.
let value = 2
let key = 3
let optional: String?
Do not coalign assignments, because if a longer variable is added to that block, then every other one needs to be realigned making an unnecessary maintenance.
let yes = true
let no = false
let maybe = false // longer var
Add enum
options line by line.
enum State {
case
blah,
bleh
}
Colinear braces only if it's a simple action.
if value > key { /* ...do something */ }
Use 1TBS bracing.
if value == key {
// ...do something
} else if value > key {
// ...do something
} else if
value < key,
key != 2 {
// ...do something else
} else {
// ...do something else
// ...do something else
}
do catch
must be placed as following:
do {
// ...try something
} catch {
// ...catch something
}
Cases together. If cases have the same value, add them line by line. Single line only if it's a single action:
switch self {
case .default: return
case .other:
// ...do something
return
case .onevalue,
.sameOneValue: return
}
Add each guard conditional statement in a new line and wrap return
in the same line of else
or in the same line as long as the code does not turn out hard to read.
guard
let opt = optional
else { return }
guard let opt = optional else { return }
If you want to add more code inside else
, then add it in a new line and make braces more spaced.
guard
let opt = optional,
key == true
else {
// ...do something
return
}
Colinear braces only if it's a simple action or empty initializer.
init() { }
func first() { /* do something */ }
If the function has more than one action or non-empty initializer, then add a new line before and after the code block.
init() {
// ...do something
}
func second() {
// ...do something
// ...do something else
}
When you have a single argument, then add it in the same line of the function. "Braces want to breathe, parentheses want to hug" (Erica Sadun - Swift Styles).
func third(one: String) {
}
When you have more than one argument, add it one line below. This way makes both paramenters in the same column and allows us to debug every parameter separately.
public func fourth(one: String,
second: String) {
}
When calling the function, call them in the same line as long as the code does not turn out hard to read.
fourth(one: "", second: "")
fourth(one: "",
second: "")
Add the return type in the same line of the last parentheses.
public func fifth(one: String,
second: String) -> Int {
return 2
}
let a = fifth(one: "",
second: "")
When you have a where
clause, add it one line below of the closing parentheses.
func sixth<C>(one: String,
two: String,
third: C) -> Int
where C: Collection, C.Iterator.Element == Character {
return 2
}
let b = sixth(one: "",
two: "",
third: [""])
Do not add them.
print( "a", "x" )
When chaining functions add the first one in the first line and the other on each line below. Make them breathe though.
let threes = (1...15)
.filter({
$0 % 3 == 0
})
.map({
"#\($0)"
})
print(threes)
Make closure as clean as possible.
Instead of doing this:
{ (index: Index) -> Void in
}
Do this:
{ index in // way much cleaner
}
Limit the use shorthand arguments ($0
, $1
, ...
) for simplest closures, such as those used when mapping, filtering and sorting.
[(0, 1), (3, 2)].map({ $0 < $1 }) // avoid
[(0, 1), (3, 2)].map(<) // do it
// TODO
// TODO
// TODO
// TODO
// TODO