Swift) Swift API Design Guidelines

4 minute read

[Swift.org](https://www.swift.org/documentation/api-design-guidelines//#fundamentals)

  • 위의 내용을 번역해보면서 이해하려고 노력해보았다.

Swift’s markdown

[Markup Overview](https://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_markup_formatting_ref/)

Quick Help markup

/// Writes the textual representation of each    ← Summary
/// element of `items` to the standard output.
///                                              ← Blank line
/// The textual representation for each item `x` ← Additional discussion
/// is generated by the expression `String(x)`.
///
/// - Parameter separator: text to be printed    ⎫
///   between items.                             ⎟
/// - Parameter terminator: text to be printed   ⎬ Parameters section
///   at the end.                                ⎟
///                                              ⎭
/// - Note: To print without a trailing          ⎫
///   newline, pass `terminator: ""`             ⎟
///                                              ⎬ Symbol commands
/// - SeeAlso: `CustomDebugStringConvertible`,   ⎟
///   `CustomStringConvertible`, `debugPrint`.   ⎭
public func print(
  _ items: Any..., separator: String = " ", terminator: String = "\n")

Naming

Promote Clear Usage

명확한 사용을 추진하세요!

  • 네이밍이 사용된 코드를 읽는 사람이 모호해하지 않기 위해 필요한 모든 단어를 포함합니다.
  • 불필요한 말은 생략합니다. 이름의 모든 단어는 사용 영역에서 중요한 정보를 전달해야 합니다.
  • type 의 제약 조건(e.g. String) 이 아닌 역할에 따라 변수, 매개변수 및 관련 유형의 이름을 지정합니다.
  • 매개변수의 역할을 명확히 하기 위해 약한 type 정보를 보충합니다.

Strive for Fluent Usage

유창한 사용을 위해 노력하세요!

  • 사용 영역이 문법적 영어 구문을 형성하도록 하는 메서드 및 기능 이름을 선호합니다.
x.insert(y, at: z)          x, insert y at z
x.subViews(havingColor: y)  x's subviews having color y
x.capitalizingNouns()       x, capitalizing nouns
  • make 로 factory methods 의 이름을 시작하십시오. e.g. x.makeIterator()
  • side-effect 에 따라 함수 및 메서드 이름 지정

      // Those without side-effects should read as noun phrases
      // e.g. 
      x.distance(to: y)
      i.successor()
        
      //Those with side-effects should read as imperative verb phrases,
      //e.g.
      print(x)
      x.sort()
      x.append(y)
    
    • mutating/nonmutating methods 쌍을 일관되게 네이밍 합니다. mutating methods 는 유사한 의미를 가지지만 instance 업데이트 대신 새 값을 반환합니다.
    • mutating methods 는 동사의 명령형을 사용하고, nonmutating methods 는 ~ed, ~ing 접미사를 사용해서 네이밍합니다.

11

    - 동사의 과거분사로 네이밍하는 것을 선호한다.
    
    ```swift
    /// Reverses `self` in-place.
    mutating func reverse()
    
    /// Returns a reversed copy of `self`.
    func reversed() -> Self
    ...
    x.reverse()
    let y = x.reversed()
    ```
    
    - 동사가 직접 목적어를 가지고 있기 때문에 `~ed` 를 추가하는 것이 문법적이지 않은 경우, `~ing` 을 추가하여 네이밍합니다.
    
    ```swift
    /// Strips all the newlines from `self`
    mutating func stripNewlines()
    
    /// Returns a copy of `self` with all the newlines stripped.
    func strippingNewlines() -> String
    ...
    s.stripNewlines()
    let oneLine = t.strippingNewlines()
    ```
    
    - 작업이 자연스럽게 명사로 설명되는 경우 nonmutating methods 로 사용하고, `form` 접두사를 적용해서 mutating methods 를 네이밍합니다.

22

  • Bollean methods 와 프로퍼티들의 사용은 nonmutating 할때, receiver 에 대한 주장으로 네이밍되어야 합니다. e.g. x.isEmpty, line1.intersects(line2)
  • 무엇인가를 설명하는 프로토콜은 명사로 읽어야 합니다. e.g. Collection
  • types, properties, variables, constants 은 명사로 네이밍 되어야 합니다.

Use Terminology Well

용어를 잘 사용하자!

  • 모호한 용어를 사용하지 마세요.
  • 확립된 의미를 고수하세요.
  • 약어를 피하세요.
    • 사용된 약어는 검색을 통해 쉽게 찾을 수 있어야 합니다.
  • 관례를 받아들이세요.

Conventions

General Conventions

  • O(1) 이 아닌 계산된 속성의 복잡성을 문서화하세요.
  • free functions 보다 메서드와 프로퍼티를 선호합니다. (free funtions 전역변수. e.g. print, min, max sin 등등)
  • 대소문자 규칙을 따릅니다. types 와 protocols 는 UpperCamelCase . 다른 것들은 lowerCamelCase .
  • 메서드는 동일한 기본 의미를 공유하거나 별개의 도메인에서 작동할때 base name 을 공유할 수 있다.

Parameters

func move(from **start**: Point, to **end**: Point)
  • 문서를 제공할 수 있도록 매개변수의 이름을 선택하세요. 중요한 설명 역할을 합니다.

      /// Replace the given `subRange` of elements with `newElements`.
      mutating func replaceRange(_ subRange: Range, with newElements: [E])
    
  • 사용을 단순화할 때 default parameters 를 활용하세요.

      let order = lastName.compare(
        royalFamilyName, options: [], range: nil, locale: nil)
        
      // use default parameters
      let order = lastName.compare(royalFamilyName)
        
      extension String {
        /// ...description...
        public func compare(
           _ other: String, options: CompareOptions = [],
           range: Range? = nil, locale: Locale? = nil
        ) -> Ordering
      }
    
  • 매개변수 목록의 끝에 기본값을 사용하는 매개변수를 위치하는 것을 선호합니다. (기본값이 없는 매개변수는 의미가 더 있고, 메소드가 호출되는 안정적인 초기사용 패턴을 제공하기 때문입니다. 그래서 앞에 두는 것을 선호합니다.)

Argument Labels

func move(**from** start: Point, **to** end: Point)
x.move(**from**: x, **to**: y)
  • 인자를 유용하게 구분할 수 없는 경우 모든 라벨을 생략합니다. e.g. min(number1, number2)
  • 값 보존, type 변환을 수행하는 initializers 의 첫번째 인수라벨을 생략합니다. e.g. Int64(someUInt32)
  • 첫 번째 인수가 전치사구의 일부를 형성할 때 인수 라벨을 지정합니다. 즉, 메서드 명에 연관되어 첫 번째 인수가 전치사구에 포함될 때 전치사 뒤에 인수 레이블을 시작한다.
// x
a.move(toX: b, y: c)
a.fade(fromRed: b, green: c, blue: d)

// o
a.moveTo(x: b, y: c)
a.fadeFrom(red: b, green: c, blue: d)
  • 위와 같지 않고 첫 번째 인수가 문법 구의 일부를 형성하는 경우는 라벨을 생략하고, base name 에 선행 단어를 추가한다. e.g. addSubveiw(y)
    • 반대로, 첫번째 인수가 문법 구문의 일부를 형성하지 않는 경우는 라벨이 있어야 함을 의미한다.
      view.dismiss(animated: false)
      let text = words.split(maxSplits: 12)
      let studentsByName = students.sorted(isOrderedBefore: Student.namePrecedes)
    
    • 기본값이 있는 인수는 생략 가능하며, 이 경우 문법 구문의 일부를 형성하지 않는 경우이므로 항상 라벨이 있어야 합니다.

Special Instructions

특별 지침!

  • API 에 표시되는 tuple member 및 closure parameters 에 라벨을 지정합니다.
  • overload sets 에서 모호성을 피하도록 제약되지 않은 다형성에 주의를 더 기울여야 합니다. (e.g. AnyAnyObject 그리고 제약되지 않은 제네릭 매개 변수)

출처:

[Swift.org](https://www.swift.org/documentation/api-design-guidelines//#fundamentals)

Categories:

Updated: