Common Swift Attributes

Jul 19, 2022#swift

An attribute provides additional information about the declaration or type. You specify an attribute by writing the @ symbol followed by the attribute’s name and any arguments that the attribute accepts:

@attribute name
@attribute name(attribute arguments)

Declaration Attributes

  • @available: Indicate a declaration’s life cycle relative to certain Swift language versions or certain platforms and operating system versions.
@available(swift 3.0.2)
@available(macOS 10.12, *)
struct MyStruct {
    /* */
}
  • @discardableResult: Suppress the compiler warning when the function or method that returns a value is called without using its result.

  • @dynamicCallable: Apply to a class, structure, enumeration, or protocol to treat instances of the type as callable functions.

@dynamicCallable
struct TelephoneExchange {
    func dynamicallyCall(withArguments phoneNumber: [Int]) {
        if phoneNumber == [4, 1, 1] {
            print("Get Swift help on forums.swift.org")
        } else {
            print("Unrecognized number")
        }
    }
}

let dial = TelephoneExchange()
dial(4, 1, 1)

@dynamicCallable
struct Repeater {
    func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, Int>) -> String {
        return
          pairs
            .map { label, count in
                repeatElement(label, count: count).joined(separator: " ")
            }
            .joined(separator: "\n")
    }
}

let repeatLabels = Repeater()
print(repeatLabels(a: 1, b: 2, c: 3, b: 2, a: 1))
  • @dynamicMemberLookup: Apply to a class, structure, enumeration, or protocol to enable members to be looked up by name at runtime. The type must implement a subscript(dynamicMember:) subscript.
@dynamicMemberLookup
struct DynamicStruct {
    let dictionary = [
        "someDynamicMember": 325,
        "someOtherMember": 787,
    ]
    subscript(dynamicMember member: String) -> Int {
        return dictionary[member] ?? 1054
    }
}
let s = DynamicStruct()

// Use dynamic member lookup.
let dynamic = s.someDynamicMember
print(dynamic)
// Prints "325"

// Call the underlying subscript directly.
let equivalent = s[dynamicMember: "someDynamicMember"]
print(dynamic == equivalent)
// Prints "true"
  • @frozen: Apply to a structure or enumeration declaration to restrict the kinds of changes you can make to the type.
  • @inlinable: The compiler is allowed to replace calls to an inlinable symbol with a copy of the symbol’s implementation at the call site.
  • @main: Indicate that it contains the top-level entry point for program flow. The type must provide a main type function that doesn’t take any arguments and returns Void.
@main
struct MyTopLevel {
    static func main() {
        // Top-level code goes here
    }
}
  • @NSManaged: Apply to an instance method or stored variable property of a class that inherits from NSManagedObject to indicate that Core Data dynamically provides its implementation at runtime, based on the associated entity description.
  • @objc: Apply to any declaration that can be represented in Objective-C.
  • @propertyWrapper: to a class, structure, or enumeration declaration to use that type as a property wrapper.
  • @resultBuilder: Apply to a class, structure, enumeration to use that type as a result builder. A result builder is a type that builds a nested data structure step by step.
  • @testable: Apply to an import declaration to import that module with changes to its access control that simplify testing the module’s code.
  • @usableFromInline: Allow to be used in inlinable code that’s defined in the same module as the declaration.

Type Attributes

  • @autoclosure: Delay the evaluation of an expression by automatically wrapping that expression in a closure with no arguments.
  • @escaping: Apply to a parameter’s type in a function or method declaration to indicate that the parameter’s value can be stored for later execution.
  • @Sendable: Apply to the type of a function to indicate that the function or closure is sendable.

Switch Case Attributes

  • @unknown: Apply to a switch case to indicate that it isn’t expected to be matched by any case of the enumeration that’s known at the time the code is compiled.