General Conventions
시간복잡도가 O(1)이 아닌 것을 명시한다(Document the complexity of any computed property that is not O(1))
- 사람들은 일반적으로 정보들을 기억하고 생각해내는데에 같은 시간이 걸리므로 특정 정보에 접근하는 것에 추가적인 시간이 들지 않는다고 생각한다. 이 때문에, 코드에서 Property에 접근하는 계산이 모두 O(1)으로 작동한다고 생각하기 쉬우며 O(1)이 아닐 경우 명시해줄 필요가 있다.
free function보다 property와 method를 더 이용해야한다(Prefer methods and properties to free functions)
- free function: Swift에서는 Global function(전역 함수)를 free function이라고 칭한다. 코드 어디에서나 사용 가능한 함수로 print(), max() 등의 함수가 있다.
- free function 사용 가능 케이스 1: 함수에 명백하게 self가 없을 때(객체에 종속적이지 않을 때)
- (질문!)free function 사용 가능 케이스 2: 함수가 unconstrained generic일 때(타입 제약이 없을 때) - 정확한 의미와 왜 가능한지?
- free function 사용 가능 케이스 3: 함수 구문이 도메인 표기의 일부일 경우(sin 함수처럼 기존에 있는 개념 자체의 함수를 나타낼 경우 전역적으로 사용 가능)
Case convention을 따른다(Follow case conventions)
- (미국 영어 기준) 일반적으로 모두 대문자로 표기되는, 앞글자만 딴 축약어의 경우 모두 대문자로 표기하거나 모두 소문자로 표기해야 한다.
- 그 외 축약어의 경우는 일반 단어로 취급한다.(축약어이지만 일반 단어처럼 사용되는 경우)
메소드는 기본 명명(base name)을 공유할 수 있다(Methods can share a base name)
- 메소드들이 기본적으로 같은 의미를 공유하고 있을 때 기본 이름을 공유할 수 있다.
- 예시의 경우, 비슷한 역할을 하지만 입력 parameter의 타입이 다를 때에 일일이 새로운 함수명을 만드는 것이 아니라 기본 함수명을 공유해도 된다.
- 다른 도메인(separate domain, i.e. 위의 예시의 경우 다른 extension)에 존재하더라도 같은 프로그램 내에 있다면 base name을 공유할 수 있다.
Parameters
문서의 의미를 전달할 수 있는, 읽을 때 자연스러운 parameter의 이름을 정해야한다(Choose parameter names to serve documentation)
- parameter를 명명한 후 그것을 기준으로 문서를 작성하는 것이 아니라 문서를 기준으로 문서를 읽듯이 읽힐 수 있는 parameter로 naming을 할 필요가 있다.
- 아래 예시의 경우 includedInResult는 메소드 정의 흐름을 어색하게 만드는 명명법이다.
parameter의 디폴트 기능을 활용해라(Take advantage of defaulted parameters)
- 단일하게 사용되는 parameter는 디폴트로 처리할 수 있다.
- 디폴트 기능을 활용함으로써 읽기 쉬운 코드를 작성할 수 있다.
- 예시의 경우, 함수를 호출할 때에 parameter options는 빈 array로, range, locale은 nil값으로 동작하게 되는데 추가적인 입력이 없다면 이 역할이 함수 내에 고정적이므로 default를 사용하여 더 짧고 명료하게 호출할 수 있다.
- 함수를 정의할 때에도 parameter가 존재할 때마다 새로운 함수를 정의하는 것보다 default를 활용하여 정의하면 명료하고 간단하게 정의할 수 있다.
디폴트가 존재하는 parameter는 뒤에 배치하고, 입력이 필요한 parameter를 앞쪽에 배치한다(Prefer to locate parameters with defaults toward the end )
- 입력이 필요하다는 의미는 메소드가 동작하는데 더 필수적인 요소라는 의미이며, 디폴트가 존재하는 parameter보다 중요도가 높을 수 있다. 그래서 중요한 parameter부터 배치하기 위해 디폴트가 존재하지 않는 parameter를 앞쪽에 배치한다.
Argument Labels
인수들이 서로 명확히 구별될 수 없는 경우 label을 생략한다(Omit all labels when arguments can’t be usefully distinguished)
- min(number1, number2)의 경우 number1과 number2의 최소값을 구하므로 순서 등의 의미가 중요하지 않고 두 요소를 구별할 필요가 없다. 이런 경우 label은 생략한다.
값의 변화가 발생하지 않고 값을 보존하는 타입 변환의 경우, 첫번째 인자의 label을 생략한다(In initializers that perform value preserving type conversions, omit the first argument label)
- 첫번째 인수는 항상 변환되는 대상(source)이어야 한다.
- 그러나 변환이 narrowing되는, 즉 변환 전보다 변환 이후의 폭(데이터의 양)이 더 좁아질 경우는 label을 한다.
- 예시의 경우 숫자를 String으로 전환하는 경우 데이터의 손실이 없이 진행되므로 변환의 대상에 label을 정할 필요가 없다.
- 반면에 UInt64에서 UInt32로 전환할 경우, UInt64가 더 큰 범위의 값을 가질 수 있기 때문에 label을 해야한다.
첫번째 인자가 전치사구에 포함될 때, 두번째 인자 등 추가적인 argument 역시 phrase에 포함되는 것이 아니라면 label을 한다.(When the first argument forms part of a prepositional phrase, give it an argument label)
- 예시의 경우 반례로서 x뿐만 아니라 y도, red뿐만 아니라 green, blue 역시 전치사 to 또는 from의 대상으로서 전치사 구에 포함되므로 전치사를 label로 활용하는 것이 아니라 메소드명에 포함시킨다.
만약 첫번째 인자가 문법적인 구를 형성하면, label을 생략한다(Otherwise, if the first argument forms part of a grammatical phrase, omit its label)
- 첫번째 인자가 문법적인 구를 형성하는게 아니면, label을 가져야한다.
- 문법적으로만 맞는 것이 아니라, 올바른 의미를 전달해야 한다.
- 디폴트값을 가진 인자들은 생략될 수 있고, 생략 가능한 경우 그 인자들로 문법적인 구를 생성하면 생략되었을 때 의미가 부정확할 수 있게되므로 생략가능한 인자들은 포함하지말고 label 값을 가져야한다.(생략 가능한 인자들을 포함해서 naming하지 말아라)
다른 모든 인자는 label한다(Label all other arguments)
keywords: free function, generic
reference: https://swift.org/documentation/api-design-guidelines/#conventions