-
사용할 때 기준으로 명확하게 작성하는 게 가장 중요하다. 메소드나 속성과 같은 개체들은 한 번만 선언하고 반복적으로 사용한다. API를 만들 때는 이러한 개체들을 이해하기 쉽고 간결하게 만드는데 중점을 주고 작성해야 한다. 사용하는 상황에서 문맥상 명확하게 이해도록 하자.
-
명확한 표현이 압축한 간결성보다 더 중요하다. 스위프트 코드는 간결하게 작성할 수 있지만, 단지 글자수를 줄여서 가장 짧은 코드를 만드는 게 목표는 아니다. 스위프트 코드의 간결성은 자연스럽게 반복적으로 재사용하는 코드(boilerplate)를 줄이는 기능과 강한 타입 시스템의 부수효과로 드러날 뿐이다.
-
모든 선언 부분에 주석을 적극적으로 작성하라. 문서를 작성하면서 얻는 통찰력은 API 설계에 큰 영향을 줄 수 있으니 미루지 말고 주석을 꼭 달자. 간단한 용어로 API 기능을 설명하지 못한다면, 설계의 문제가 있을 가능성이 높다.
-
그 이름을 사용하는 부분의 코드를 읽는 사람에게 혼란을 줄 수 있는 단어는 피한다.
-
불필요한 단어는 생략한다.
이름의 모든 단어는 사용자 관점에서 주요한 정보를 제공해야만 한다.
-
변수, 매개변수, 연관 타입은 선언한 타입이나 제약사항 보다는 역할에 맞는 이름을 갖도록 한다.**
-
매개변수 역할을 명확하게 넣어서 부족한 타입 정보를 보완한다.
-
메소드나 함수를 사용할 때 영어 문장을 작성하는 것처럼 느끼도록 제공한다.
-
팩토리 메소드 이름은 "make"로 시작한다. 예)
x.makeIterator()
-
초기화(생성) 메소드나 팩토리 메소드는 첫 번째 인자에 추가적인 설명을 포함하지 않도록 한다. 예)
x.makeWidget(cogCount: 47)
-
함수나 메소드 이름은 사이드 이펙트(side-effects)에 따라 다르게 정한다
-
사이드 이펙트가 없는 경우는 명사형으로 작성한다. 예)
x.distance(to: y)
,i.successor()
. -
사이드 이펙트가 있는 경우에는 명령형 동사로 작성한다. 예)
print(x)
,x.sort()
,x.append(y)
. -
가변/불변 메소드 이름을 함께 고려해야 한다.
-
동사로 표현하면 자연스럽게 "ed"나 "ing"를 붙여서 불변 메소드 이름을 만들 수 있다.
가변(Mutating)
x.sort()
,x.append(y)
불변(Nonmutating)
z = x.sorted()
,z = x.appending(y)
- 동작을 명사로 표현하기 적합한 경우에는 가변 메소드 이름에 "form-"을 머릿말로 붙인다.
불변
x = y.union(z)
,j = c.successor(i)
가변
y.formUnion(z)
,c.formSuccessor(&i)
-
-
불변으로 사용할 때 Boolean 메소드나 프로퍼티를 사용할 때는 리턴값을 받아서 단언 구문(Assertion)처럼 읽도록 한다. 예)
x.isEmpty
,line1.intersects(line2)
. -
무언가를 설명하는 프로토콜은 명사로 읽어야 한다. 예)
Collection
-
기능이나 가능성을 표현하는 프로토콜은 -able, -ible, -ing 등을 붙여서 표현한다. 예)
Equatable
,ProgressReporting
. -
그 외에 상수, 변수, 속성, 타입들은 명사로 읽어야 한다.
-
애매한 용어를 피한다. '피부(skin)'를 '표피(epidermis)'라고 하지말고, 더 쉽게 의미를 전달할 수 있는 표현이 있으면 그걸 선택하라. 전문 용어(Term of Art)는 필수적인 소통 도구지만, 사용하지 않을 경우 놓칠 수 있는 중요한 의미를 꼭 표현해야 하는 경우만 사용하세요.
-
전문 용어를 사용한다면 기존 의미에 맞춰 사용한다. 일반적인 용어가 애매하거나 불명확한 것을 정확하게 표현하기 위해서만 기술적인 용어를 사용하는 것이 좋다.
- 전문가를 놀라게 하지마라: 기존에 친숙하게 사용하던 용어에 전혀 새로운 의미를 부여한다면 선배들이 놀라거나 화를 낼지도 모른다.
- 초보자를 헷갈리게 하지마라: 웹에서 용어를 찾아 공부하는 사람들에게도 용어의 전형적인 의미가 중요하다.
-
축약어를 피한다. 전문 용어면서 표준 형태가 아닌 약자는 잘못 풀어쓰거나 오해를 할 수 있다.
-
선례를 받아들인다. 모든 초보자를 위해 용어를 적지 말고 기존 문화에서 쓰이는 용어가 적합하다.
-
변수, 상수, 함수, 메서드, 타입 등의 이름은 유니코드에서 지원하는 어떤 문자(한글, 한자, 영문, 숫자, 이모티콘 등)라도 사용할 수 있다.
다만 다음과 같은 예외 경우는 사용할 수 없다.
- 스위프트에서 미리 정한 예약어 또는 키워드
- 해당 코드 범위 내에서 미리 사용되는 기존 이름과 동일한 이름
- 연산자로 사용될 수 있는 기호(+,-,*,/)
- 숫자로 시작하는 이름
- 공백이 포함된 이름
-
대소문자 표기법을 따른다.
- 함수, 메서드, 인스턴스 이름은 첫 글자를 소문자로 사용하는
LowerCamelCase
를 사용한다. - 클래스, 구조체, 익스텐션, 프로토콜, 열거형(enum) 이름은 타입의 이름이기 때문에 첫 글자를 대문자로 사용하는
UpperCamelCase
로 표기한다. - 명령 구문 뒤에 세미콜론(;)을 붙이는 것은 선택 사항이다.
(But, 굳이 붙이지 말 것)
- 대소문자를 구분하므로 유의한다. (Var와 var를 다르게 인식함.)
- 함수, 메서드, 인스턴스 이름은 첫 글자를 소문자로 사용하는
-
O(1) 복잡도가 아닌 연산 프로퍼티(Computed Property)는 설명을 만든다. 대부분 사람들은 저장 프로퍼티에 익숙해서 프로퍼티 값에 접근하지 않는다고 생각하는데, 생각이 어긋날 수 있을 때 경고해야 한다.
-
소속이 없는 자유로운 함수를 만들기 보다는 메소드나 속성을 만든다. 다음의 특별한 경우에만 함수를 고려하라.
- 명확하게
self
가 없을 때 :min(x,y,z)
- 제약없는 제네릭 함수인 경우 :
print(x)
- 함수 표현이 특정한 도메인 표기법을 준수하는 경우 :
sin(x)
- 명확하게
-
메소드가 같은 의미를 갖고 있거나 특정한 도메인 영역에서만 동작을 하는 경우에는 기본 이름을 공유할 수 있다.
func move(from start: Point, to end: Point)
-
문서화 할 수 있는 매개 변수 이름을 선택한다. 함수나 메소드를 사용할 때 매개변수가 감춰져있더라도 여전히 중요한 역할을 한다.
-
매개변수 기본값을 지정해서 편리함을 더한다. 매개 변수에 흔히 넘기는 값 자체를 기본값으로 활용하라.
-
기본 인자값은 매개 변수 목록에서 마지막 위치부터 넣는다. 기본 인자값이 없는 매개변수는 메소드에서 더 중요한 역할을 하고, 메소드를 호출하는 곳에서 안정적으로 초기화하는 형태로 사용할 수 있다.
func move(from start: Point, to end: Point)
x.move(from: x, to: y)
-
레이블이 인자값을 구분하는데 도움이 안되면 모든 레이블을 생략한다. 예)
min(number1, number2)
,zip(sequence1, sequence2)
-
초기화 생성 함수(이니셜라이저)에서 다른 타입 값을 받아서 변환하고 보관하는 (값보존 변환) 경우에는 첫 번째 인자 레이블을 생략한다. 예)
Int64(someUInt32)
-
첫 번째 인자값이 (영어에서) 전치사 형태라면 인자값 레이블을 표기한다.
-
첫 번째 인자값이 (전치사가 아니라) 다른 문법상의 구문이라면 레이블은 생략하고,
x.addSubview(y)
처럼 기본 이름에 의미있는 단어를 뒤에 붙여도 된다. -
그 외에 모든 경우는 레이블을 표기하라.
-
튜플 멤버에 레이블을, 클로저 매개변수에 이름을 표기하라.
-
Any
나AnyObject
, 제약없는 제네릭 매개변수처럼 제약없는 다형성(polymorphism)은 오버로드할 때 혼동하지 않도록 주의하라.