I'm declaring a protocol that inherits multiple protocols. What's the best style suggestion for open curly brace and linewrapping the parents?

Hi there, I'm implementing a protocol that has multiple parents, and I'm unsure of the most preferred way to line-wrap the parents, and where to put the open curly brace. I want the protocol style to stay consistent with how I declare my functions too.

This is how I declare my functions, but this style looks weird for declaring protocols with multiple parents:

func doSomething(
    foo: String, 
    bar: String, 
    baz: String
)  {
    ...
}

For protocols, here are a few of what my declarations could look like. Any suggestions on which is common and more preferred?

(A)

protocol MyProtocol: 
    ParentA, 
    ParentB, 
    ParentC, 
    ParentD {
    let name: String
}

(B)

protocol MyProtocol: 
    ParentA, 
    ParentB, 
    ParentC, 
    ParentD 
{
    let name: String
}

(C) (the alignment got weird, but all the parents are supposed to be aligned here)

protocol MyProtocol: ParentA, 
                                  ParentB, 
                                  ParentC, 
                                  ParentD {
    let name: String
}

(D) (the alignment got weird, but all the parents are supposed to be aligned here)

protocol MyProtocol: ParentA, 
                                  ParentB, 
                                  ParentC, 
                                  ParentD 
{
    let name: String
}
1 Like

While there's no official style and everyone has their own preferences, swift-format will do something close to (B).

The general rule it uses is that open braces should go on the same line, unless that line is the indented continuation of a previous line and putting the brace on the same line would make the next line (also indented) be confusable with the lines above it; in that case, the brace is moved to the next line and unindented.

6 Likes

I prefer

protocol MyProtocol: ParentA, ParentB, ParentC, ParentD {
    let name: String
}

but it’s just a style choice, so go with whatever you like.

1 Like

an alternative to having a large number of unconditionally-implied conformances is to instead provide default implementations that conforming types can opt into:

protocol P:Equatable, Sendable
{
}
extension P where Self:CustomStringConvertible
{
    ...
}
extension P where Self:ExpressibleByStringLiteral
{
    ...
}
extension P where Self:ExpressibleByArrayLiteral
{
    ...
}

i find the number of intrinsic implied conformances is usually much lower than the number of “incidental” conformances to other protocols that a protocol merely works well with.

3 Likes

I currently do this, but then some times the line length gets extremely long (as with more complex architectures).