cat swift/linting-formattazione-coerenza.md
Linting, formattazione e coerenza
Uno stile coerente riduce attrito: formattazione, linting e convenzioni devono aiutare il team, non sostituire il giudizio.
Il codice professionale non deve solo funzionare. Deve essere leggibile in modo coerente da più persone nel tempo.
Formattazione e linting servono a ridurre discussioni inutili:
- spaziatura;
- ordinamento;
- lunghezza;
- pattern rischiosi;
- convenzioni di naming;
- import inutili.
Non sostituiscono il design. Liberano attenzione per il design.
Formattazione
La formattazione risponde a domande come:
- dove vanno gli a capo?
- come indentiamo closure lunghe?
- come allineiamo parametri?
- come ordiniamo import?
Uno strumento di formattazione rende queste scelte automatiche.
Nel mondo Swift puoi incontrare strumenti come swift-format o strumenti adottati dal team. L’importante è non formattare a mano in modo incoerente.
Un esempio pratico:
let risultato = prodotti.filter { $0.disponibile }.map { $0.nome }.sorted()
Un formatter può trasformarlo in una forma più leggibile quando la pipeline cresce:
let risultato = prodotti
.filter { $0.disponibile }
.map { $0.nome }
.sorted()
Non cambia il comportamento. Riduce il carico visivo.
Linting
Un linter segnala pattern indesiderati.
Esempi:
- force unwrap non giustificato;
- funzioni troppo lunghe;
- nomi non coerenti;
try!;- codice non usato;
- complessità eccessiva.
Non ogni warning è una verità assoluta. Ma ogni warning merita una decisione.
Regole locali
Un corso o team dovrebbe avere poche regole chiare:
- evitare
!salvo casi motivati; - preferire
let; - niente
Task.detachedsenza commento; - no
@unchecked Sendablesenza giustificazione; - nomi di dominio in italiano o inglese, ma non misti senza motivo;
- test per errori di dominio.
Le regole migliori proteggono il progetto, non il gusto personale.
Configurazione minima
Una policy utile sta nel repository, non nella memoria del team.
Esempio di sezione README:
## Style
- Prefer `let` unless mutation is required.
- Avoid force unwrap except in test fixtures or after explicit validation.
- Do not use `Task.detached` without documenting why structured concurrency is not enough.
- Run `swift format lint --recursive Sources Tests` before opening a PR.
Anche se il progetto non usa ancora un file di configurazione, rendere esplicite le regole evita discussioni ricorrenti.
Formattare in CI
Il controllo deve essere riproducibile.
Esempio concettuale:
swift format lint --recursive Sources Tests
Oppure:
swiftlint lint
Il comando concreto dipende dagli strumenti scelti dal progetto.
Evitare churn
Non riformattare tutto il repository mentre stai cambiando una funzione. Genera diff enormi e rende difficile fare review.
Strategia:
- introdurre formattazione una volta;
- poi applicarla automaticamente;
- evitare modifiche di stile fuori scope.
Per una codebase già esistente, fai una PR solo di formattazione. Dopo quella PR, ogni modifica futura deve rispettare lo stile. Mischiare refactor logico e riformattazione di massa rende quasi impossibile capire cosa è cambiato davvero.
Eccezioni motivate
Ogni regola deve prevedere eccezioni rare.
let prezzo = Price(100)!
In un test, un force unwrap su una fixture controllata può essere accettabile. In codice di produzione su dati esterni, quasi mai.
L’obiettivo non è eliminare ogni simbolo !. È sapere perché esiste.
Stile e API design
Il lint non può decidere se un nome è buono nel dominio.
Questo passa il lint:
func process(_ item: Item) -> Item
Ma può essere pessimo.
Questo è più utile:
func applica(_ coupon: Coupon, a carrello: Carrello) throws -> Carrello
La coerenza meccanica è solo il pavimento.
Checklist
Per un setup sano:
- formatter scelto è documentato;
- linter scelto è documentato;
- comandi eseguibili da terminale;
- CI controlla build, test e stile;
- regole non troppo rumorose;
- eccezioni motivate;
- niente riformattazioni casuali fuori scope.
Esempio di policy breve
Build: swift build
Test: swift test
Format check: swift format lint --recursive Sources Tests
Regole manuali: niente DTO nel dominio, niente rete nei test unitari, niente singleton nascosti nei use case.
Questa policy collega stile meccanico e architettura. Il formatter sistema gli spazi; il team protegge i confini.
Esercizio
Definisci una mini policy per CouponKit:
- quando è ammesso
!; - come gestire
Task.detached; - come nominare funzioni di dominio;
- quale comando usare per formattare;
- quale comando usare in CI.
Poi prendi una lezione precedente e individua tre punti in cui uno stile automatico aiuterebbe.