web-dev-qa-db-fra.com

qu'est-ce que «où soi» dans l'extension de protocole

J'ai vu tellement d'exemples avec le format ci-dessous

extension Protocolname where Self: UIViewController

Quel est where Self dans l'extension de protocole. Je n'ai pas pu trouver la documentation à ce sujet.

19
Mini2008

Cette syntaxe est: https://developer.Apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//Apple_ref/doc/uid/TP40014097-CH25-ID521

Considérer:

protocol Meh {
    func doSomething();
}

//Extend protocol Meh, where `Self` is of type `UIViewController`
//func blah() will only exist for classes that inherit `UIViewController`. 
//In fact, this entire extension only exists for `UIViewController` subclasses.

extension Meh where Self: UIViewController {
    func blah() {
        print("Blah");
    }

    func foo() {
        print("Foo");
    }
}

class Foo : UIViewController, Meh { //This compiles and since Foo is a `UIViewController` subclass, it has access to all of `Meh` extension functions and `Meh` itself. IE: `doSomething, blah, foo`.
    func doSomething() {
        print("Do Something");
    }
}

class Obj : NSObject, Meh { //While this compiles, it won't have access to any of `Meh` extension functions. It only has access to `Meh.doSomething()`.
    func doSomething() {
        print("Do Something");
    }
}

Ce qui suit donnera une erreur de compilation car Obj n'a pas accès aux fonctions d'extension Meh.

let i = Obj();
i.blah();

Mais ce qui suit fonctionnera.

let j = Foo();
j.blah();

En d'autres termes, Meh.blah() n'est disponible que pour les classes de type UIViewController.

32
Brandon

Voici un exemple qui explique à quoi sert where self: UIViewController

protocol SBIdentifiable {
    static var sbIdentifier: String { get }
}

extension SBIdentifiable where Self: UIViewController {
    static var sbIdentifier: String {
        return String(describing: self)
    }
}

extension UIVieWcontroller: SBIdentifiable { }

class ViewController: UIViewController {
  func loadView() {
  /*Below line we are using the sbIdentifier which will return the 
   ViewController class name.
    and same name we would mentioned inside ViewController 
    storyboard ID. So that we do not need to write the identifier everytime. 
   So here where Self: UIViewController means it will only conform the protocol of type UIViewController*/ 

  let viewController = self.instantiateViewController(withIdentifier: 
    self.sbIdentifier) as? SomeBiewController
  }
}
5
Hussain Shabbir

Vous pouvez trouver le même exemple ici : WWDC2015-408 , ( Je recommande vivement de le regarder , il illustre la raison)

Et aussi, un autre exemple similaire est Extensions avec une clause Where générique

struct Stack<Element> {
    var items = [Element]()
    mutating func Push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

La clause where ajoute une exigence à l'extension, de sorte que l'extension ajoute la méthode isTop (_ :) uniquement lorsque les éléments de la pile sont équitables.

extension Stack where Element: Equatable {
    func isTop(_ item: Element) -> Bool {
        guard let topItem = items.last else {
            return false
        }
        return topItem == item
    }
}
2
boog