Objective-C 在方法命名上可能不太讨初学者喜欢,但是往往有一定经验的 Objective-C 开发者都会爱上它的方法命名方式。因为详细的参数名和几乎完整及标准的英文可以将方法准确地描述出来,很多时候进行 Objective-C 开发只需要依赖 IDE 的补全,甚至连文档都可以不看。比如 Objective-C 里的 NString 类里有个这样的方法:

- (BOOL)writeToFile:(NSString *)path 
         atomically:(BOOL)useAuxiliaryFile 
           encoding:(NSStringEncoding)enc 
              error:(NSError **)error

不仅定义的时候非常清楚,而且实际使用的时候,因为我们需要把方法名写完整,所以阅读的时候不需要查阅文档。我们可以清楚的标明各个参数的含义:

[str writeToFile:aPath atomically:YES 
        encoding:NSUTF8StringEncoding error:&err];

该方法表示“将 str 写入文件 aPath,使用原子写入并将编码设置为 UTF,如果发生错误则将其存储在 err 中”。

Swift 的方法命名继承并发展了这一优点。上述方法在Swift中的定义是:

func writeToFile(_ path: String,
      atomically useAuxiliaryFile: Bool,
        encoding enc: UInt,
           error error: NSErrorPointer) -> Bool

同样的 API 在 Objective-C 和 Swift 中的声明除了必要的类型的切换以外,其余基本保持了一致。而我们注意到 Swift 版本中的第一个参数的前面加了下划线 _,这代表在调用这个方法时,我们不应该把这个参数名显式地写出来。于是,在 Swift 中对该方法的调用是:

str.writeToFile(aPath, atomically:true, 
                encoding:NSUTF8StringEncoding, error: &err)

为了方便比较,我们重写一下刚才的Objective-C调用:

[str writeToFile:aPath atomically:YES 
                encoding:NSUTF8StringEncoding error:&err];

两者在形式和结构上高度一致。可以说,为了达到这样的视觉效果,苹果故意省略了第一个参数的名称,然后保留了其他参数的名称,以与Cocoa框架保持一致。

实际上,即使是我们不在参数前加任何标记来显式地表明是否需要写名称的情况下,对于何时强制需要名称标签,何时强制不要名称标签,也是有规则的。在类型的 init 方法中是需要加入标签的,比如下面例子的 color 和 weight 都不能省略:

class Car {
    init(color: UIColor, weight: Int) {
        //...
    }
}

let car = Car(color: UIColor.redColor(), weight: 10)

对于实例方法,当我们调用它时,Swift 会忽略第一个参数的标签并强制后续参数名称:

extension Car {
    func moveToX(x: Int, y: Int) {
        //...
    }
}

car.moveToX(10, y: 20)

类方法也是如此:

extension Car {
    class func findACar(name: String, color: UIColor) -> Car? {
        var result: Car?
        //...
        return result
    }
}

let myPorsche = Car.findACar("Porsche", color: UIColor.yellowColor())

但有一个例外,就是如果该方法是全局方法,则默认省略参数名:

// 注意,现在不在 Car 中,而是在一个全局作用域
func findACar(name: String, color: UIColor) -> Car? {
    var result: Car?
    //...
    return result
}

let myFerrari = findACar("Ferrari", UIColor.redColor())

为什么全局方法和本地方法的默认参数标签有这么大的区别?这当然不是克里斯·拉特纳在写这篇文章时乐意随口写的事情。其实这是因为很多原来的底层C函数都是在全局作用域中声明的,所以所有匿名参数的使用都和原来的调用方式一致。

尽管不同的作用域对方法/函数调用的参数名称有严格的规则,但它们差异的后果是,在面试期间在 Swift 中正确使用白板代码可能并不容易。

当然,以上种种我们都可以通过添加 #_ 或者是显式地加上标签名称来在调用时强制要求添加或者不添加参数名称。但是我们在实践中最好是遵循 Swift 的默认规则。在大多数时候,我们需要的是普通方法调用和初始化方法调用:对于普通方法,匿名第一个参数,并强制要求其他的参数名称;对于初始化方法,强制要求所有参数使用命名 (除非有特殊情况或完全没有歧义的情况下可以省略名称)。这样做有助于保证写出来的方法风格与整个平台统一,并且在调用时保持原有的“代码即文档”的优良特性。

转自 :点击打开链接