我的iOS应用程序中有以下结构:
struct MyStruct<T> {
var property1: T
var property2: T
init(property1: T, property2: T) {
self.property1 = property1
self.property2 = property2
}
init(allPropertiesWith value: T) {
self.property1 = value
self.property2 = value
}
}
我还有 2 个没有共同祖先的类:
class A { }
class B { }
在我的应用程序中,我有MyStruct<A>
、MyStruct<B>
、MyStruct<A?>
、MyStruct<B?>
的实例,我在以下函数中使用它们:
func f1(myStrurct: MyStruct<A?>) { }
func f2(myStrurct: MyStruct<A>) { }
func g2() {
f1(myStrurct: MyStruct<A?>(property2: A()))
}
/* I also have the same functions for MyStruct<B> and MyStruct<B?> */
我无法修改f1
,f2
和g2
。这就是为什么我创建了 2 个扩展来简化MyStruct<T>
的初始化:
extension MyStruct where T == A? {
init(property1: T) {
self.property1 = property1
self.property2 = nil
}
init(property2: T) {
self.property1 = nil
self.property2 = property2
}
}
extension MyStruct where T == B? {
init(property1: T) {
self.property1 = property1
self.property2 = nil
}
init(property2: T) {
self.property1 = nil
self.property2 = property2
}
}
如您所见,这些扩展几乎相同。是否可以仅使用 1 个扩展来重构它?
您可以使A
和B
(或任何需要它的类(都符合虚拟协议,并检查该协议是否T
。
protocol MyStructProtocol {
}
class A: MyStructProtocol { }
class B: MyStructProtocol { }
extension MyStruct where T == MyStructProtocol? {
init(property1: T) {
self.property1 = property1
self.property2 = nil
}
init(property2: T) {
self.property1 = nil
self.property2 = property2
}
}
在Rakesha Shastri提供的答案中,我发现我可以使用protocol
来重构我的代码。但是,为了能够使用此解决方案,我需要重写应用程序的其他部分。我尝试将 Rakesha Shastri 的解决方案添加到我的应用程序中,并使用 Swift 3、Swift 4 或 Swift 4.2(Xcode 10.0 中提供的所有 Swift 版本(编译它,但每次我都收到编译器错误。这意味着目前没有办法解决我在这个问题中描述的问题。
您不必扩展任何内容即可创建如此简单的构造函数。在下面查看结构定义的修改版本:
struct MyStruct<T> {
var property1: T?
var property2: T?
init(property1: T? = nil, property2: T? = nil) {
if T.self == String.self {
self.property1 = property1
self.property2 = nil
}
else if T.self == Int.self {
self.property1 = nil
self.property2 = property2
}
}
init(allPropertiesWith value: T) {
self.property1 = value
self.property2 = value
}
}
然后,您可以根据需要使用以下行初始化它们。
MyStruct<String>(property2: "sadsad")
MyStruct<Int>(property1: 23)