Unused setter value is likely a mistakeSW-W1004Duplicate key in dictionary is likely a mistakeSW-E1000Default parameters should always be positioned at the endSW-W1001Duplicate conditions in branch instruction is likely a mistakeSW-W1005Enum should always have unique casesSW-W1007Use of an insecure version of TLS protocolSW-S1002Use of an insecure block cipher modeSW-S1003Use of an insecure cipher algorithmSW-S1004Prefer using `min()` or `max()` over `sorted().first` or `sorted().last`SW-P1011Prefer using `.first(where:)` over `.filter { }.first` in collectionsSW-P1007Prefer `contains` over `range(of:) != nil` and `range(of:) == nil`SW-P1012Force unwrapping should be avoidedSW-W1023An object should only remove itself as an observer in `deinit`SW-W1028Prefer `contains` over comparing `filter(where:).count` to zeroSW-P1001Prefer `reduce(into:_:)` over `reduce(_:_:)` for copy-on-write typesSW-P1010Prefer using `.allSatisfy()` or `.contains()` over `reduce(true)` or `reduce(false)`SW-P1000Prefer `contains` over using `filter(where:).isEmpty`SW-P1002Prefer `contains` over `first(where:) != nil` and `firstIndex(where:) != nil`SW-P1003Prefer checking `isEmpty` over comparing collection to an empty array or dictionary literalSW-P1004`@IBInspectable` should be applied to variables only, have its type explicit and be of a supported typeSW-W1006`try!` statements should be avoidedSW-W1008When the index or the item is not used, `.enumerated()` can be removedSW-W1002The initializers declared in compiler protocols such as `ExpressibleByArrayLiteral` shouldn’t be called directlySW-W1027Avoid using `dynamic` and `@inline(__always)` togetherSW-W1026Subclasses of `NSObject` should implement `isEqual` instead of `==`SW-W1029Passing `NSNumber.init` or `NSDecimalNumber.init` as a function reference is dangerous as it can cause the wrong initializer to be used, causing crashes; use `.init(value:)` insteadSW-W1030Delegate protocols should be class-only so they can be weakly referencedSW-R1029Prefer using `.last(where:)` over `.filter { }.last` in collectionsSW-P1009TODOs and FIXMEs should be resolvedSW-D1000Extensions shouldn't override declarationsSW-R1020Duplicate import statements are redundant and can be removedSW-W1000Unused parameters in a closure can be replaced with the underscore identifierSW-W1009Audit: Use of legacy functions to generate random values can be insecureSW-A1000Comparing two identical operands is likely a mistakeSW-W1015Unit tests marked `private` are silently skippedSW-W1016Void functions should not be used with ternary operatorsSW-W1018Use of unrestricted base URL in web viewSW-S1000Use of insufficient number of iterations during hash computationSW-S1001Audit: Use of potentially insecure options during XML parsingSW-A1001Prefer using `Array(seq)` over `seq.map { $0 }` to convert a sequence into an ArraySW-R1000Always specify message when invoking `fatalError()`SW-R1021Do not name an enum member as `none`SW-R1025An `XCTFail` call should include a description of the assertionSW-R1032`@IBOutlet`s shouldn’t be declared as weakSW-W1020`fileprivate` should be avoidedSW-R1027Delegates should be weak to avoid reference cyclesSW-W1025Prefer using the `hash(into:)` function instead of overriding `hashValue`SW-R1001Use named arguments in multiline Swift closuresSW-R1004Swift constructors are preferred over legacy convenience functionsSW-R1008Prefer `.zero` over explicit init with zero parametersSW-R1009Returning values from a function returning `Void` should be avoidedSW-R1014Extensions shouldn’t be used to group code within the same source fileSW-R1028Force casts should be avoidedSW-W1013self refers to the unapplied `NSObject.self()` method, which is likely not expectedSW-W1017Implicitly unwrapped optionals should be avoided when possibleSW-W1022Prefer using `Set.isDisjoint(with:)` over `Set.intersection(_:).isEmpty`SW-R1007Shorthand syntactic sugar should be used, i.e. `[Type]` instead of `Array<Type>`SW-C1003`@objc` is redundant when used with implicit Objective-C attributeSW-R1011Setter access control should be different from the variable's access levelSW-R1013Avoid using unneeded break statementsSW-R1018Fallthrough should be avoidedSW-W1012Types used for hosting only static members should be implemented as a caseless enum to avoid instantiationSW-R1030String enum values can be omitted when they are equal to the enum case nameSW-R1031Follow conventions while naming typesSW-C1000Missing documentation commentSW-D1001Use shorthand syntax for optional bindingSW-C1001Prefer `flatMap` over `map` followed by `reduce([], +)`SW-P1008`where` clauses are preferred over a single `if` inside a `for` loopSW-R1005`nil` coalescing operator is never evaluated as it's in RHSSW-R1010Redundant `Optional` initializationSW-R1012Declare operators as static functions instead of free functionsSW-R1015Use `#unavailable`/`#available` instead of `#available`/`#unavailable` with an empty bodySW-R1017Do not explicitly call `.init` methodSW-R1022Unused control flow label should be removedSW-W1010Unimplemented functions should be marked as `unavailable`SW-W1014Use `assertionFailure()` and `preconditionFailure()` over `assert(false)`SW-W1021Generic type name should only contain alphanumeric characters, start with an uppercase character and span between 1 and 20 characters in lengthSW-C1002Prefer checking `isEmpty` over comparing `count` to zeroSW-P1005The constant literal should be placed on the right-hand side of the comparison operatorSW-R1003Catch statements should not declare error variables without type castingSW-R1019Empty `XCTest` method should be avoidedSW-W1031Prefer checking `isEmpty` over comparing `string` to an empty string literalSW-P1006Function with cyclomatic complexity higher than thresholdSW-R1002
Swift logoSwift/
SW-R1015

Declare operators as static functions instead of free functionsSW-R1015

Minor severityMinor
Anti-pattern categoryAnti-pattern

Declaring operators as free functions in Swift can lead to several issues and make the code harder to read and maintain.

Cluttered Namespace: When operators are declared as free functions, they pollute the global namespace and make it harder to find other functions and variables. This can lead to naming conflicts, especially if multiple libraries define operators with the same name.

Inconsistency: Swift’s standard library defines many operators as static functions on the type they operate on. Declaring custom operators as free functions breaks this convention and can make the code harder to understand and remember.

Limited Functionality: Free functions cannot be overridden or accessed through inheritance, which limits their functionality. This can make it harder to extend the functionality of operators or customize them for specific use cases.

Inefficient Method Dispatch: When operators are declared as free functions, the Swift compiler has to perform dynamic method dispatch to determine the correct implementation to use. This can be slower than using a static function.

In summary, declaring custom operators as free functions can pollute the global namespace, break conventions, limit functionality, and lead to inefficient method dispatch. It is generally recommended to declare operators as static functions on the type they operate on.

Bad Practice

func +<T>(lhs: T, rhs: T) -> T {
  // implementation
}
static func +<T>(lhs: T, rhs: T) -> T {
    // implementation
}