본문 바로가기

프로그래밍 언어/Swift

읽기 좋은 코드 작성하기 #2 Conventions

반응형
 

Swift.org

Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.

www.swift.org

Swift API Design Guidelines에 정의된 컨벤션 규칙을 알아보자!

 

Conventions 컨벤션

 

1. 복잡도가 O(n)이 아니라면 복잡도를 주석으로 남기기

/// Time Complexity: O(n^3)
func test() {
    a.forEach { b in
        b.forEach { c in
            c.forEach { d in
                ...
            }
        }
    }
}

 

2. 전역 함수 대신에 메서드와 프로퍼티 사용하기

 

3. type, protocol의 이름은 UpperCamelCase, 나머지는 lowerCamelCase를 따르기

but, 미국 영어에서 보통 all upper case로 사용되는 Acronyms and initialisms은 통일성 있게 사용

var utf8Bytes: [UTF8.CodeUnit]
var isRepresentableAsASCII = true
var userSMTPServer: SecureSMTPServer

 

4. 기본 뜻이 같거나 서로 구별되는 도메인에서 작동하는 메서드는 이름을 동일하게 사용할 수 있다.

기본적으로 같은 동작을 하기 때문에 같은 이름을 사용하는 것이 권장된다.

 good 

extension Shape {
  /// Returns `true` iff `other` is within the area of `self`.
  func contains(_ other: Point) -> Bool { ... }

  /// Returns `true` iff `other` is entirely within the area of `self`.
  func contains(_ other: Shape) -> Bool { ... }

  /// Returns `true` iff `other` is within the area of `self`.
  func contains(_ other: LineSegment) -> Bool { ... }
}

 

5. default parameter 사용하기

  • method를 여러 개 나열하기보다 default parameter 사용하기
  • default parameter는 parameter list 뒷부분에 두기 

 Bad   

extension String {
  /// ...description 1...
  public func compare(_ other: String) -> Ordering
  /// ...description 2...
  public func compare(_ other: String, options: CompareOptions) -> Ordering
  /// ...description 3...
  public func compare(
     _ other: String, options: CompareOptions, range: Range) -> Ordering
  /// ...description 4...
  public func compare(
     _ other: String, options: StringCompareOptions,
     range: Range, locale: Locale) -> Ordering
}

 good 

extension String {
  /// ...description...
  public func compare(
     _ other: String, options: CompareOptions = [],
     range: Range? = nil, locale: Locale? = nil
  ) -> Ordering
}

 

6. 의미없는 메서드의 label은 생략 가능하다.

e.g. min(number1, number2), zip(sequence1, sequence2)

 

7. overload set에서의 모호함을 피하기 위해, 제약 없는 다형성에 각별히 주의하기

e.g. Any, AnyObject, unconstrained generic parameters

 Bad   

struct Array {
  /// Inserts `newElement` at `self.endIndex`.
  public mutating func append(_ newElement: Element)

  /// Inserts the contents of `newElements`, in order, at
  /// `self.endIndex`.
  public mutating func append(_ newElements: S)
    where S.Generator.Element == Element
}

var values: [Any] = [1, "a"]
values.append([2, 3, 4]) // [1, "a", [2, 3, 4]] or [1, "a", 2, 3, 4]?

 good 

두 번째 overload의 이름을 더 명시적으로 지정

struct Array {
  /// Inserts `newElement` at `self.endIndex`.
  public mutating func append(_ newElement: Element)

  /// Inserts the contents of `newElements`, in order, at
  /// `self.endIndex`.
  public mutating func append(contentsOf newElements: S)
    where S.Generator.Element == Element
}

var values: [Any] = [1, "a"]
values.append(contentsOf: [2, 3, 4]) // [1, "a", 2, 3, 4]

 

 

반응형