-
API Design GuidelinesIOS/기록 2021. 2. 9. 19:31
Application Programming Interface
swift.org/documentation/api-design-guidelines/#use-terminology-well
Swift.org
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
swift.org
API Design Guidelines
목차
Fundamentals
● 사용의 지점(the point of use)을 명확하게 하는 것은 가장 중요한 목표입니다.
method 및 property와 같은 엔터티는 한 번만 선언되지만 반복적으로 사용됩니다.
이러한 용도를 명확하고 간결하게 만들기 위해 API를 설계하십시오.
설계를 평가(evaluating)할 때 선언(declaration)을 읽는 것만으로는 충분하지 않습니다.
항상 사용 사례를 조사하여 문맥 상(in context) 명확하게 보이도록 하십시오.
● 간결함보다 명확성이 더 중요합니다.
비록 Swift 코드가 간결하게 될 수 있을지라도,
최소한의 문자로 가능한 가장 작은 코드를 사용하는 것은 목표가 아닙니다.
Swift 코드에서의 간결함은
강력한 유형 시스템(the strong type system)의 부작용(side-effect)이며,
자연스럽게 반복 사용 어구(boilerplate)를 줄이는 특징입니다.
● 모든 선언(declaration)에 대한 문서 주석(documentation comment)을 작성하십시오.
문서 작성을 통해 얻은 통찰력(insight)은 설계에 큰 영향을 미칠 수 있으므로 미루지 마십시오.
당신이 만든 API의 기능을 간단한 용어로 설명하는 데 문제가 있는 경우,
당신은 잘못된 API를 설계했을 수 있습니다.○ 스위프트의 dialect of Markdown를 사용하십시오.
○ 선언되는 엔티티를 설명하는 요약(Summary)으로 시작하십시오.
종종 API는 선언(declaration)과 요약(Summary)으로부터 완전히 이해하게 될 수 있습니다.
- 요약(Summary)에 집중하십시오. 가장 중요한 부분입니다.
많은 훌륭한 문서 주석은 훌륭한 요약(summary)에 지나지 않습니다. - 가능하면 마침표로 끝나는 single sentence fragment을 사용하십시오.
완전한 문장을 사용하지 마십시오. - 함수 또는 메서드가 어떤 작업을 하는지와 어떤 것을 반환하는지 설명하십시오.
(omitting null effects and Void returns -> null효과와 Void 반환을 생략함으로써)
참고 : 드물지만 위의 popFirst와 같은 경우에 요약(Summary)은 세미콜론으로 구분된 여러 문장으로 구성됩니다.
- subscript가 접근(accesses)하는 것이 무엇인지 설명하십시오 :
/// Accesses the `index`th element. subscript(index: Int) -> Element { get set }
- initializer가 만드는 것이 무엇인지 설명하십시오 :
/// Creates an instance containing `n` repetitions of `x`. init(count n: Int, repeatedElement x: Element)
- 다른 모든 선언(declaration)에서, 선언된 엔티티가 무엇인지 설명하십시오 :
/// A collection that supports equally efficient insertion/removal /// at any position. struct List { /// The element at the beginning of `self`, or `nil` if self is /// empty. var first: Element? ...
○ 선택적으로 하나 이상의 단락(paragraphs)과
글 머리 기호 항목(bullet items)을 이용하여 선언(declaration)이 무엇인지 설명하십시오.
단락(paragraphs)은 빈 줄로 구분되며 완전한 문장(complete sentences)을 사용합니다.(이때 글 머리 기호 항목은 "-"로 표시하는 듯 하다.)
(글 머리 기호 항목(bullet items)은 아래 표로 나와 있다.)
/// 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")
Parameters section (파라미터 섹션)
Symbol commands- 적절한 때마다 요약(summary) 이외의 정보를 추가하려면
symbol documentation markup 요소(elements)를 사용하십시오 - symbol command syntax으로 인식된 글 머리 기호 항목(bullet items)을 알고 사용하십시오.
Xcode와 같은 인기 있는 개발 도구는
아래 표에 있는 키워드로 시작하는 글 머리 기호 항목(bullet items)을 특별하게 처리합니다.
Naming
명확한 사용방법을 장려합니다. (Promote Clear Usage)
● 그 name이 사용되는 코드를 읽는 사람을 위하여,
필요한 모든 단어들을 모호함을 없앨 목적으로 포함(include)합니다.
(이때 모든 단어들은 API에 사용되는 단어들을 의미하는 듯 하다.)
예를 들어, collection 내의 지정된 위치에서 요소(element )를 제거하는 method를 생각해보십시오.
method signature에서 at이라는 단어(word)를 생략하면
제거할 요소(element)의 위치(인덱스)를 표시하기 위해 x를 사용하는 대신
method가 x와 동일한 요소(element)를 (배열 같은 곳에서) 검색하고
제거한다는 것을 독자에게 암시할 수 있습니다.
● 불필요한 단어(word)는 생략하십시오.
name에 있는 모든 단어(word)는 사용되는 위치(the use site)에서 중요한 정보를 전달해야 합니다.
의도를 명확히 하거나 의미를 명확하게 하기 위해 더 많은 단어가 필요할 수 있지만
독자(the reader)가 이미 가지고 있는 정보와 중복되는 단어는 생략해야 합니다.
특히 type 정보를 반복하는 단어는 생략하십시오.
이 경우 Element라는 단어(word)는 호출 위치(The call site)에서 중요한 내용을 추가하지 않습니다.
따라서 아래와 같은 API가 더 좋습니다.
경우에 따라 모호성을 피하기 위해 반복되는 type 정보가 필요하지만
일반적으로 type보다는 매개 변수의 역할(parameter's role)을 설명하는 단어를 사용하는 것이 좋습니다.
자세한 내용은 다음 항목을 참조하십시오.
● 그것들의 type 제약(constraints)이 아닌 역할(role)에 따라
변수(variable), 매개 변수(parameter) 및 관련된(associated) type의 이름을 지정합니다.(타입이 아니라 역할로 이름을 지정하라는 말 같다.)
이러한 방식으로 유형 이름을 용도 변경하면 명확성(clarity)과 표현력(expressivity)을 최적화할 수 없습니다.
대신 the entity’s role을 나타내는 이름을 선택하려고 노력하십시오.
연결된 타입(associated type)이 프로토콜 제약 조건에 너무 밀접하게 연결되어 프로토콜 이름이 역할이라면,
프로토콜 이름에 프로토콜을 추가하여 충돌을 방지합니다.
protocol Sequence { associatedtype Iterator : IteratorProtocol } protocol IteratorProtocol { ... }
● 약한 타입 정보(weak type information)를 보완하여
매개 변수의 역할(parameter’s role)을 명확하게 합니다.
특히 매개 변수 타입(parameter type)이
NSObject, Any, AnyObject 또는 Int 또는 String과 같은
기본 타입(fundamental type)인 경우에
사용 지점(point of use)의 type 정보 및 context는 의도를 완전히 전달하지 못할 수 있습니다.
이 예에서 선언(declaration)은 명확해질 수 있지만 사용 위치(use site)는 모호합니다.
명확성을 회복(restore)하기 위해서 약하게 타입된(weakly typed)
각 매개 변수의 앞에 역할을 설명하는 명사를 붙입니다.
Strive for Fluent Usage
● 문법적인 영어 구 형식으로 use site를 만든 method와 function 이름을 선호합니다.
Prefer method and function names that make use sites form grammatical English phrases. (무슨 뜻??)
(아래는 단순히 코딩만 되어있는 반면에,
위의 코딩은 오른쪽에 영어로 분명히 그 역할이 나타나 있는 것을 볼 수 있다.
문법적인 규칙을 명확히 하여 누구나 보기 쉽게 표현되어 있는 것이 인상적이다.)첫 번째 매개 변수 또는 두 번째 매개 변수가 호출 의미의 중심이 아닌 경우에
유창성(fluency)이 저하되는 것은 허용됩니다.
● factory method의 이름을 "make"로 시작합니다. 예: x.makeIterator().
● 이니셜 라이저와 팩토리 메서드(factory methods)의 호출에 대한 첫 번째 매개 변수는
기본 이름(base name)으로 시작하는 구문을 형성해서는 안됩니다.예 : x.makeWidget(cogCount: 47)
예를 들어 이러한 호출에 대한 첫 번째 매개 변수는 기본 이름(base name)과
동일한 구문의 일부(part of the same phrase)로 읽히지 않습니다.
(base name이 뭐지?? 아래의 경우 base name은 Color, factory.makeWidget, Link 를 의미하는 듯 하다.)
아래에서 API 작성자는 첫 번째 매개 변수로 문법적 연속성(grammatical continuity)을 만들려고 했습니다.
실제로 이 지침(guideline)은 인수 레이블(argument labels)에 대한 지침(guideline)과 함께
그 호출(call)이 값 보존 형식 변환(value preserving type conversion.)을 수행하지 않는 한
첫 번째 인수에 레이블이 있음을 의미합니다. (무슨 말이지??)
● their side effect에 따라 function과 method들의 이름을 작성합니다.
( side - effect는 잠재적인 부작용을 의미합니다. )
( https://www.hyeonk-lab.tistory.com/43 )- side-effects이 없는 것들은 명사구로서 읽어야 합니다.
예 : x.distance(to: y), i.successor(). - side-effects가 있는 것들은 명령형 동사구로서 읽어야 합니다.
예 : print(x), x.sort(), x.append(y). - Mutating/nonmutating method 쌍(pairs)은 일관되게 이름을 지정합니다.
mutating method는 종종 유사한 의미를 가진 nonmutating method을 가집니다.
그러나 mutating method는 인스턴스를 제자리(in-place)에서 업데이트하는 대신 새 값을 반환합니다. (뭔말이지??)- 연산(operation)이 동사로 자연스럽게 설명되는 경우에는
mutating method에 동사의 명령형을 사용하고
"ed" 또는 "ing"를 대응되는 nonmutating method의 뒤에 붙입니다.
- 연산(operation)이 동사로 자연스럽게 설명되는 경우에는
동사의 과거분사(the verb’s past participle )(일반적으로 "ed" 추가)를 사용하여
the nonmutating variant의 이름을 지정하는 것을 선호합니다. :
/// Reverses `self` in-place. mutating func reverse() /// Returns a reversed copy of `self`. func reversed() -> Self ... x.reverse() let y = x.reversed()
동사에 직접 목적어가 있기 때문에 "ed"를 추가하는 것이 문법적으로 오류가 있는 경우에는
"ing"을 추가하여 동사의 현재 분사(present participle)를 사용하여 nonmutating의 이름을 지정합니다.
/// 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()
연산(operation)이 명사로 자연스럽게 설명되는 경우에는
nonmutating method에 명사를 사용하고
대응되는 mutating method에는 "form"접두사를 적용하여 이름을 지정합니다.
● bool 메서드와 bool property의 사용은 그 사용이 nonmutating일 때
수신자(receiver)에 대한 assertion으로 읽어야 합니다.
( assertion은 가정 설정문이다. 예 : isEmpty는 비어있다는 가정 설정문이다. )
ko.wikipedia.org/wiki/%ED%91%9C%EB%AA%85예 : x.isEmpty , line1.intersects(line2).
● 무엇인가를 설명하는 프로토콜은 명사로 읽어야 합니다.
(예 : Collection).
● 기능을 설명하는 프로토콜은 able, ible 또는 ing 접미사를 사용하여 이름을 지정해야 합니다.
(예 : Equatable , ProgressReporting)
● 다른 type, property, 변수 및 상수의 이름은 명사로 읽어야 합니다.
용어(Terminology)를 잘 사용하세요.
Term of Art 명사-특정 분야 또는 직업 내에서 정확하고 특수한 의미를 갖는 단어 또는 구.
● 더 일반적인 단어가 의미를 잘 전달하는 경우에는 모호한 용어를 사용하지 마십시오.
“skin(피부)”가 당신의 목적에 적합하다면 “epidermis(표피)”라고 말하지 마십시오.
예술의 용어(Terms of art)는 필수적인 커뮤니케이션 도구이지만,
예술의 용어(Terms of art)를 사용하지 않으면 손실될 수 있는 중요한 의미를 포착하는 데만 사용해야 합니다.
● 예술 용어(Terms of art)를 사용하는 경우 기존의 의미를 고수하십시오.
더 일반적인 단어가 아닌 전문 용어를 사용하는 유일한 이유는
모호하거나 불명확한 것을 정확하게 표현하기 때문입니다.
따라서 API는 허용되는 의미에 따라 엄격하게 용어를 사용해야 합니다.
전문가를 놀라게 하지 마십시오 :
누구든 이미 이 용어에 익숙한 사람은 우리가 새로운 의미를 발명한 것처럼 보이면 놀라고 화를 낼 것입니다.
초보자를 혼동하게 하지 마십시오 :
용어를 배우려는 사람은 누구나 웹 검색을 통해 그 의미를 찾을 수 있습니다.
● 약어(abbreviations)를 사용하지 마십시오.
약어(abbreviations), 특히 비표준 용어(non-standard ones)는
효과적인 예술 용어(terms-of-art)입니다.
왜냐하면 이해하는 것은 약어(abbreviations)를 축약되지 않은 형식(non-abbreviated forms)으로
올바르게 번역하는 데 달려 있기 때문입니다.
사용하는 약어(abbreviations)의 의도된 의미는 웹 검색을 통해 쉽게 찾을 수 있습니다.
● 선례(precedent)를 받아들이십시오.
기존 문화를 준수하는 대신 전체 초보자를 위한 용어를 최적화하지 마십시오.
초보자가 List의 의미를 더 쉽게 이해할 수 있을지라도
List와 같은 단순화된 용어를 사용하는 것보다
연속 데이터 구조 Array의 이름을 지정하는 것이 좋습니다.
배열은 현대 컴퓨팅의 기본이므로
모든 프로그래머는 배열이 무엇인지 알고 있거나 곧 알게 될 것입니다.
대부분의 프로그래머가 익숙한 용어를 사용하면
웹 검색 및 질문에 대한 보답을 받을 수 있습니다.
수학과 같은 특정 프로그래밍 영역(domain) 내에서 sin(x)와 같이 널리 사용되는 용어가 verticalPositionOnUnitCircleAtOriginOfEndOfRadiusWithAngle (x)와 같은 설명 문구보다 선호됩니다.
이 경우, 약어(abbreviations)를 피하기 위해 선례(precedent)가 지침(guideline) 보다 중요합니다.
완전한 단어는 sine이지만 “sin (x)”는 수십 년 동안 프로그래머 사이에서, 그리고
수세기 동안 수학자 사이에서 일반적으로 사용되었습니다.
규칙 (Conventions)
일반적인 규칙 (General Conventions)
● O(1)이 아닌 모든 computed property의 복잡성을 문서화하십시오.
사람들은 종종 mental model로서 stored property를 가지고 있기 때문에
property access가 significant computation을 포함하지 않는다고 가정합니다.
그 가정이 위반될 수 있는 경우 반드시 그들에게 알리십시오.
● free functions보다 method와 property를 선호합니다.
free function은 특별한 경우에만 사용됩니다.(Global functions(전역 함수) 즉, 코드 어디에서나 사용할 수 있는 함수들을 swift에서는 free function이라고 한다.)
(hongdonghyun.github.io/2019/11/Swift-Closure/)
특별한 경우
1. 명백한 self가 없을 때 free function을 사용합니다.
min(x, y, z)
2. function이 unconstrained generic일 때 free function을 사용합니다.
print(x)
3. function 문법(syntax)이 설정된 도메인 표기법(notation)의 일부인 경우에 free function을 사용합니다.
sin(x)
● case 규칙(convention)을 따르십시오.
type과 프로토콜의 이름은 UpperCamelCase 입니다.
(Class, Struct, Enumeration, Extension, Protocol)
그 외에는 모두 lowerCamelCase입니다.
미국 영어에서 일반적으로 모두 대문자로 표시되는
두문자어와 이니셜(Acronyms and initialisms)은
대소문자 규칙에 따라 균일하게 대소문자를 구분해야 합니다.
( 두문자어 : 첫 글자를 맞추어 만든 말 )
var utf8Bytes: [UTF8.CodeUnit] var isRepresentableAsASCII = true var userSMTPServer: SecureSMTPServer
다른 약어(acronyms)는 일반 단어로 취급해야 합니다.
var radarDetector: RadarScanner var enjoysScubaDiving = true
● method는 동일한 기본 의미를 공유하거나 별개의 도메인에서 작동할 때
기본 이름(base name)을 공유할 수 있습니다.예를 들어 method가 본질적으로 동일한 작업을 수행하기 때문에 다음이 권장됩니다.
기하학적(geometric) type과 컬렉션은 별도의 도메인이므로 동일한 프로그램에서도 괜찮습니다.
그러나 이러한 index method는 의미 체계가 다르며 이름이 달라야 합니다.
마지막으로, "반환 type에 대한 오버 로딩" (“overloading on return type”)은 type 유추가 있을 때
모호성을 유발하므로 피하십시오.
Parameters
func move(from start: Point, to end: Point)
● 문서를 제공할 매개 변수(parameter) 이름을 선택하십시오.
매개 변수(parameter) 이름이 함수 또는
메서드의 사용 지점(method’s point of use)에 나타나지 않더라도
중요한 설명 역할을 합니다.
문서를 읽기 쉽게 하려면 이 이름을 선택하십시오.
예를 들어, 이러한 이름은 문서를 자연스럽게 읽도록 만듭니다.
그러나 이것들은 문서를 어색하고 문법적이지 않게 만듭니다.
● 일반적인 사용을 단순화할 때 기본 매개 변수(defaulted parameters)를 활용하십시오.
일반적으로 사용되는 단일 값이 있는 모든 매개 변수가 기본값(default) 후보입니다.
기본 인수는 관련 없는 정보를 숨겨 가독성을 향상시킵니다. 예를 들면 :
훨씬 더 간단해질 수 있습니다.
기본 인수(Default arguments)는 일반적으로 API를 이해하려는 모든 사람에게
인지 부담(a lower cognitive burden)이 적기 때문에 method families를 사용하는 것보다 선호됩니다.
위의 내용은 간단하지 않을 수 있지만 다음보다 훨씬 간단합니다.
method family의 모든 구성원(member)은 사용자가 별도로 문서화하고 이해해야 합니다.
그중에서 결정하기 위해서는 사용자가 모든 것을 이해해야 하며,
가끔 놀라운 관계(occasional surprising relationships)는
(예 : foo (bar : nil) 와 foo()는 항상 동의어는 아닙니다.)
대부분의 사소한 차이를 확인하는 지루한 프로세스로 만듭니다.
(method family는 method에 있는 구성요소들의 집합으로 해석하면 될 듯 하다.)
동일한 문서. 기본값이 있는 단일 방법을 사용하면 훨씬 뛰어난 프로그래머 경험을 얻을 수 있습니다.
● 매개 변수(Parameter) 목록 끝에 기본 값이 있는 매개 변수(Parameter)를 찾는 것이 좋습니다.
기본값(default)이 없는 매개 변수(Parameter)는
일반적으로 method의 의미 체계(semantics)에 더 중요하며
method가 호출되는 안정적인 초기 사용 패턴을 제공합니다.
인수 레이블 (Argument Labels)
func move(from start: Point, to end: Point) x.move(from: x, to: y)
● 인수를 유용하게 구분할 수 없는 경우에는 모든 라벨을 생략하세요.
예 : min(number1, number2) , zip (sequence1, sequence2)
● value preserving type conversions(타입 변환)를 수행하는 이니셜 라이저에서
첫 번째 인수 레이블(first argument label)을 생략하십시오.
예 : Int64(someUInt32)
(In initializers that perform value preserving type conversions, omit the first argument label ->번역 ??)
첫 번째 인수는 항상 변환의 소스(the source of the conversion)여야 합니다.
extension String { // Convert `x` into its textual representation in the given radix init(_ x: BigInt, radix: Int = 10) ← Note the initial underscore } text = "The value is: " text += String(veryLargeNumber) text += " and in hexadecimal, it's" text += String(veryLargeNumber, radix: 16)
그러나 “축소(narrowing)” type 변환에서는 축소(the narrowing)를 설명하는 레이블이 권장됩니다.
extension UInt32 { /// Creates an instance having the specified `value`. init(_ value: Int16) ← Widening, so no label /// Creates an instance having the lowest 32 bits of `source`. init(truncating source: UInt64) /// Creates an instance having the nearest representable /// approximation of `valueToApproximate`. init(saturating valueToApproximate: UInt64) }
type 변환을 보존하는 값(A value preserving type conversion)은 단일 형태(monomorphism)입니다.
즉, 소스 값의 모든 차이가 결과 값의 차이를 초래합니다.
예를 들어, Int8에서 Int64로의 변환은
모든 고유한 Int8 값이 고유한 Int64 값으로 변환되기 때문에 값이 보존됩니다.
그러나 다른 방향으로의 변환은 값을 보존할 수 없습니다.
Int64에서 표현할 수 있는 값은 Int8에서 표현할 수 있는 것보다 더 많은 가능한 값이 있습니다.
참고 : 원래 값을 검색하는 기능(ability)은 변환(conversion)이 가치 보존인지 여부와 관계가 없습니다.
● 첫 번째 인수가 전치사 구(prepositional phrase)의 일부를 구성할 때 인수 레이블을 지정하십시오.
인수 레이블(argument label)은 일반적으로 전치사(preposition)에서 시작해야 합니다.
( 전치사에서 시작?? havingLength 이게 인수 레이블이고
removeBoxes havingLength가 전치사 구라는 말인 것 같음 )예 : x.removeBoxes (havingLength : 12)
처음 두 인수(argument)가 단일 추상화(single abstraction)의 일부를 나타내는 경우에는 예외(exception)가 발생합니다.
이러한 경우 추상화(abstraction)를 명확하게 유지하려면
전치사(preposition) 뒤에 인수 레이블(argument label)을 시작하십시오.
● 위와 다른 경우인 첫 번째 인수(first argument)가
문법적 구문의 일부(part of a grammatical phrase)를 형성하는 경우에는
레이블을 생략하고 기본 이름(base name)에 선행 단어(preceding word)를 추가합니다.
예 : x.addSubview(y)
( 이때는 base name이 add이고 선행 단어가 Subview인 듯 )
( add Subview y 로서 문법적 구문이 되는 건가?? )
이 가이드라인은 첫 번째 인수가 문법 구문의 일부( part of a grammatical phrase )를
구성하지 않는 경우에는 레이블이 있어야 함을 의미합니다.
문구가 올바른 의미를 전달하는 것이 중요합니다.
아래는 문법적이지만 잘못된 것을 나타냅니다.
또한 기본 값(default values)이 있는 인수는 생략할 수 있으며
이 경우 문법 구의 일부( part of a grammatical phrase )를 형성하지 않으므로
항상 레이블이 있어야 합니다.
● 다른 모든 인수에는 레이블을 지정하십시오.
Special Instructions
● API에 나타나는 튜플 멤버에 레이블을 지정하고
API에 나타나는 클로저 매개 변수에 이름을 지정하십시오.
(Label tuple members and name closure parameters where they appear in your API.)
이 이름들은 설명력(explanatory power)이 있고
문서 주석(documentation comments)에서 참조할 수 있으며
튜플 멤버에 대한 표현적인 접근(expressive access)를 제공합니다.
(이 이름들은 byteCount와 reallocated 그리고 capacityChanged를 의미하는 듯 하다.)
/// Ensure that we hold uniquely-referenced storage for at least /// `requestedCapacity` elements. /// /// If more storage is needed, `allocate` is called with /// `byteCount` equal to the number of maximally-aligned /// bytes to allocate. /// /// - Returns: /// - reallocated: `true` iff a new block of memory /// was allocated. /// - capacityChanged: `true` iff `capacity` was updated. mutating func ensureUniqueStorage( minimumCapacity requestedCapacity: Int, allocate: (_ byteCount: Int) -> UnsafePointer<Void> ) -> (reallocated: Bool, capacityChanged: Bool)
클로저 매개 변수( closure parameter )에 사용되는 이름은
최상위 함수( top-level function )의 매개 변수 이름( parameter names )처럼 선택해야 합니다.
호출 사이트( the call site )에 나타나는 클로저 인수( closure argument )에 대한 레이블은 지원되지 않습니다.
● 제약이 없는 다형성(unconstrained polymorphism)을 사용하여
오버로드 세트(overload sets)의 모호성(ambiguities)을 피하십시오.
( 예 : Any, AnyObject 및 제약이 없는 제네릭 매개 변수(unconstrained generic parameters) )
예를 들어 아래와 같은 overload set를 고려하십시오.
이러한 메서드는 의미론적 패밀리(a semantic family)를 형성하고
인수의 type은 처음에는 뚜렷하게 구별됩니다.
그러나 Element가 Any 인 경우 단일 요소(single element)는
일련의 요소(sequence of element)와 동일한 type을 가질 수 있습니다.
모호함을 제거하려면 second overload의 이름을 더 명시적(explicitly)으로 지정하십시오.
새 이름이 문서 주석(the documentation comment)과 더 잘 일치하는지 확인하십시오.
이 경우 문서 주석(the documentation comment)을 작성하는 행위가
실제로 문제를 API 작성자의 관심(API author’s attention)으로 가져왔습니다.
(In this case, the act of writing the documentation comment actually brought the issue to the API author’s attention. 번역 ??)
728x90'IOS > 기록' 카테고리의 다른 글
Life cycle (0) 2021.02.04 Auto Layout 개념 정리 (0) 2021.01.29 스토리보드 컴포넌트 조사 (0) 2021.01.28 AppProject 속성 조사 (0) 2021.01.28 info.plist 조사 (0) 2021.01.28 - 요약(Summary)에 집중하십시오. 가장 중요한 부분입니다.