【问题标题】:How can I add an OR generic type constraint on a function that accepts Any如何在接受 Any 的函数上添加 OR 泛型类型约束
【发布时间】:2015-07-29 07:48:38
【问题描述】:

我有一个接受可变参数的初始化程序,但我希望参数只是以下两种类型之一:

  • 一个自定义类,比如MyCustomNSOperation
  • (MyCustomNSOperation, () -> Bool) 的元组

如何在 Swift 2.0 中实现这一点?我目前的初始化程序是这样写的,但我认为它太宽松了:

init(items: Any ...) {

}

在课堂上的某个地方,我遍历所有项目,检查它们的类型,如果它不是我想要限制的两种类型之一,我会抛出一个fatalError

for i in 0..<self.items.count {
    guard self.items[i] is MyCustomNSOperation || self.items[i] is (MyCustomNSOperation, () -> Bool) else {
        fatalError("Found unrecognised type \(self.items[i]) in the operation chain")
    }
}

如果是,我执行另一个函数的两个重载版本之一。

我也查看了协议组合,但强制类型约束逻辑是 AND,而不是 OR(即,项目必须符合 两种 类型,而不仅仅是其中一种)。

【问题讨论】:

    标签: ios iphone swift foundation


    【解决方案1】:

    我只是将这些对象抽象成一个协议并在你的类中使用它,并使用结构而不是元组:

    protocol MyItem {
        func doSomething()
    }
    
    class MyCustomNSOperation: NSOperation, MyItem {
        func doSomething() {
            print( "MyCustomNSOperation is doing something..." )
        }
    }
    
    struct OperationWithClosure: MyItem {
        let operation: MyCustomNSOperation
        let closure: () -> Bool
    
        func doSomething() {
            print( "OperationWithClosure is doing something..." )
        }
    }
    
    
    class MyClass {
    
        let items: [MyItem]
    
        init(items: MyItem...) {
            self.items = items
        }
    
        func doSomethingWithItems() {
            for item in items {
                item.doSomething()
            }
        }
    }
    

    【讨论】:

    • 我真的很喜欢这个简洁的解决方案。 (而且我也很喜欢原来的问题。)我有一个问题:将OperationWithClosure 设为struct 而不是将其声明为class 并给它一个init 有什么好处。
    • 该结构会自动合成一个初始化程序,允许您为每个属性提供一个值,并且在使用它时可以获得内置的不变性和值语义。也有缺点——例如,如果你想检查相等性或使用收集方法和过滤器并在内部依赖 ==,那么你有责任将其设为 Equitable 并实现 == 运算符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2021-07-04
    • 2012-06-05
    • 2020-09-16
    • 2022-06-11
    • 1970-01-01
    相关资源
    最近更新 更多