在 API 中给闭包参数和元组成员加上标签
这些名字有解释说明的作用,可以出现在文档注释中,并且给元组成员一个形象的入口。
/// 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
) -> (reallocated: Bool, capacityChanged: Bool)
用在闭包中时,虽然从技术上来说它们是参数标签,但你应该把它们当做参数名来选择和解释(文档中)。闭包在方法体中被调用时跟调用方法时是一致的,方法签名从一个不包含第一个参数的方法名开始:
allocate(byteCount: newCount * elementSize)
要特别注意那些不受约束的类型(譬如,Any,AnyObject和一些不受约束的范型参数),以防在重载时产生歧义。
譬如,考虑如下重载:
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<
S : SequenceType where S.Generator.Element == Element
>(newElements: S)
}
这些方法组成了一个语义族(semantic family),第一个参数的类型是明确的。但是当Element 是Any时,一个单独的元素和一个元素集合的类型是一样的。
var values: [Any] = [1, "a"]
values.append([2, 3, 4]) // [1, "a", [2, 3, 4]] or [1, "a", 2, 3, 4]?
为了避免歧义,让第二个重载方法的命名更加明确。
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<
S : SequenceType where S.Generator.Element == Element
>(contentsOf newElements: S)
}
注意新命名是怎样更好地匹配文档注释的。在这种情况下,写文档注释时实际上也在提醒 API 作者自己注意问题。