Расширить протокол с несколькими ограничениями для одного или другого - Swift - PullRequest
0 голосов
/ 03 июля 2018

Я хочу расширить протокол реализацией по умолчанию, которая удовлетворяет ограничению OR (||).

class A { }
class B { }

protocol SomeProtocol { }

/// It will throw error for || 
extension SomeProtocol where Self: A || Self: B { 
}

1 Ответ

0 голосов
/ 03 июля 2018

Вы не можете расширить протокол с помощью OR, как вы не можете сделать это в if let, потому что с этим компилятор выводит тип self или var, поэтому, если он соответствует 2 типам, компилятор не ' Я не знаю, какой у него тип.

(Когда вы вводите self. Или любой var. Компилятор всегда знает, какой тип var в типе компилятора, в этом случае он будет во время выполнения). Поэтому самый простой способ - сделать так, чтобы эти 2 типа соответствовали протоколу, и сделать расширение этого протокола. Таким образом, компилятор знает, что self соответствует протоколу, и ему нет дела до точного типа Self (но вы сможете использовать только свойства, объявленные в протоколе).

protocol ABType {
// Properties that you want to use in your extension.
} 

class A: ABType, SomeProtocol { }
class B: ABType, SomeProtocol { }

protocol SomeProtocol { }

extension SomeProtocol where Self: ABType { 
}

Также, если вы хотите применить расширение к обоим типам, вы должны сделать это один за другим.

extension A: SomeProtocol { }
extension B: SomeProtocol { }

// Глупый пример: (В данном случае это не очень полезно, но просто показать, как заставить 2 класса соответствовать протоколу и сделать его расширение с помощью метода, объявленного в этом протоколе, и создания реализации по умолчанию.)

protocol ABType {
    func getName()
}

class AClass: ABType {
    func getName() {
        print ("A Class")
    }
}

class BClass: ABType, someProtocol {
    func getName()  {
        print ("B Class")
    }
}

protocol someProtocol {
    func anotherFunc()
}

extension someProtocol where Self: ABType {
    func anotherFunc() {
        self.getName()
    }
}

let a = AClass()
// a.anotherFunc() <- Error, A cant call anotherFunc
let b = BClass()
b.anotherFunc()
...