方便故障初始化程序自分配



我正在尝试为NSURL编写一个初始化器,它可能会在失败时抛出。

我非常希望它看起来像这样。

extension NSURL {
convenience init?(string: String, throwOnNil: Bool) throws {
if let URL = NSURL(string: string) {
self = URL
} else if throwOnNil {
throw MyURLError(string: string)
} else {
return nil
}
}
}

但该语法不再受支持:error: cannot assign to value: 'self' is immutable

该语法仅适用于struct和enum

这是我唯一想到的

extension NSURL {
convenience init?(string: String, throwOnNil: Bool) throws {
if throwOnNil && NSURL(string: string) == nil {
throw MyURLError(string: string)
}
self.init(string: string)
}
}

它构造了两次URL。

救命我找不到更好的方法。


更新

事实证明,初始化器中的自赋值适用于结构和枚举,但不适用于类。我理想代码的基础是一个结构。

不能像Objective-C那样在Swift中重新定义类(引用类型)的self。当init运行时,对象已经被分配。在init中,您只需要初始化分配的对象,而不是返回不同的对象(而是nil)。此外,如果init?失败,它会立即传播,您无法捕获nil状态。

查看"Failable Initializers"博客文章你可能认为你可以。但如果仔细观察,这篇文章只显示值类型的初始化。即Intstruct,而Colorenum

我认为其基本原理是,在值类型中,self是实际值,而在引用类型中,self是指向未完全初始化的对象的特殊事物。

一种解决方法是使用@price ringo建议的工厂方法。

另一种变通方法——在这种情况下可能特别合适——是以将CCD_ 12封装在自己的CCD_。特别合适,因为URL应该是Swift中的值类型。。。示例:

struct URL {
let url : NSURL?
init(string: String) throws {
if let url = NSURL(string: string) {
self.url = url
// or extract the values and push to struct in an even more Swifty
// way
}
else {
throw URLError()
}
}
// define methods which wrap url ...
}

取决于哪一个更合适。

您是否考虑过NSURL上的工厂方法?它能让你在大部分时间里到达那里。

extension NSURL {
static func initialize(string: String, throwOnNil: Bool) throws -> NSURL? {
if let URL = NSURL(string: string) {
return URL
} else if throwOnNil {
throw MyURLError(string: string)
} else {
return nil
}
}
}

最新更新