我曾经在Objective-C中使用早期返回/黄金路径编写代码。我在Swift中尝试了这种方法,并注意到早期返回的代价是在涉及选项时使用强制解包运算符(!
)。
采用计算目录大小的方法。首先,黄金路径版本:
private func calculateSize_GoldenPath(directory:String) -> UInt64 {
let fileManager = NSFileManager.defaultManager()
var error : NSError?
var contents = fileManager.contentsOfDirectoryAtPath(directory, error: &error) as [String]?
if contents == nil {
NSLog("Failed to list directory with error \(error)")
return 0
}
var size : UInt64 = 0
for pathComponent in contents! {
let path = directory.stringByAppendingPathComponent(pathComponent)
let attributes : NSDictionary? = fileManager.attributesOfItemAtPath(path, error: &error)
if (attributes == nil) {
NSLog("Failed to read file size of \(path) with error \(error)")
continue
}
size += attributes!.fileSize()
}
return size;
}
请注意我对!
和contents
变量使用attributes
运算符的方式。
我假设过度使用!
运算符会破坏期权的目的和他们带来的类型安全性。这就是我觉得上面的方法应该在Swift中编码以避免强制解包:
private func calculateSize_IfLet(directory:String) -> UInt64 {
let fileManager = NSFileManager.defaultManager()
var error : NSError?
if let contents = fileManager.contentsOfDirectoryAtPath(directory, error: &error) as? [String] {
var size : UInt64 = 0
for pathComponent in contents {
let path = directory.stringByAppendingPathComponent(pathComponent)
if let attributes : NSDictionary = fileManager.attributesOfItemAtPath(path, error: &error) {
size += attributes.fileSize()
} else {
NSLog("Failed to read file size of \(path) with error \(error)")
}
}
return size
} else {
NSLog("Failed to list directory with error \(error)")
return 0
}
}
然而,通过使用if let
,我无法再提前返回。如果某些方法没有使用早期返回而有些方法没有,那么我最终会得到一个混合编码风格的项目。
我的问题是,有没有办法以黄金路径的方式编码而不诉诸强制解包当涉及期权?
答案 0 :(得分:0)
就个人而言,我会使用方法的提取,在这种情况下,将pathComponent部分提取到一个单独的方法中,从而避免多个缩进和笨拙的代码,这些代码将概念上的代码分开在一起。
private func calculateSize_IfLet(directoryPath:String) -> UInt64 {
var size : UInt64 = 0
let fileManager = NSFileManager.defaultManager()
var error : NSError?
if let contents = fileManager.contentsOfDirectoryAtPath(directoryPath, error: &error) as? [String] {
size = self.calculateSizeOfDirectory(directoryPath, contents:contents)
} else {
NSLog("Failed to list directory with error \(error)")
}
return size
}
private func calculateSizeOfDirectory(directoryPath:String, contents:[String]) -> UInt64 {
var size : UInt64 = 0
for pathComponent in contents {
var error : NSError?
let fileManager = NSFileManager.defaultManager()
let path = directoryPath.stringByAppendingPathComponent(pathComponent)
if let attributes : NSDictionary = fileManager.attributesOfItemAtPath(path, error: &error) {
size += attributes.fileSize()
} else {
NSLog("Failed to read file size of \(path) with error \(error)")
}
}
return size
}