扩展现有协议以使用默认工具实现另一个协议

Avn*_*arr 22 protocols swift protocol-extension

是否可以通过扩展将协议合规性添加到不同的协议?

例如,我们希望A符合B:

protocol A {
  var a : UIView {get}
}

protocol B {
  var b : UIView {get}
}
Run Code Online (Sandbox Code Playgroud)

我想给B类的对象提供B的默认实现(合规性)

// This isn't possible
extension A : B {
  var b : UIView {
    return self.a
  }
}
Run Code Online (Sandbox Code Playgroud)

动机是在需要B的情况下重用A的对象而不创建我自己的"桥"

class MyClass {
  func myFunc(object : A) {
    ...
    ...
    let view = object.a 
    ... do something with view ...

    myFunc(object)      // would like to use an 'A' without creating a 'B'
  }

  func myFunc2(object : B) {
    ...
    ...
    let view = object.b
    ... do something with view ...

  }
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,我们可以扩展一个类来实现一个协议

class C {
  let C : UIView
}

// this will work
extension C : B {
  var B : UIView {
    return self.c
  }
}
Run Code Online (Sandbox Code Playgroud)

和协议可以提供默认实现

extension A {
  // a default implementation
  var a : UIView {
     return UIView()
  }
}
Run Code Online (Sandbox Code Playgroud)

ABa*_*ith 18

扩展时A,您可以指定该类型也符合B:

extension A where Self: B {
    var b : UIView {
        return self.a
    }
}
Run Code Online (Sandbox Code Playgroud)

然后让你的类型符合AB,例如

struct MyStruct : A, B {
    var a : UIView {
        return UIView()
    }
}
Run Code Online (Sandbox Code Playgroud)

由于协议扩展的情况下,MyStruct将能够使用ab,即使只有a在开始实施MyStruct:

let obj = MyStruct()
obj.a
obj.b
Run Code Online (Sandbox Code Playgroud)

  • 我过去曾经使用过"Where:B ......",但它仍然需要定义你的"MyStruct"."MyStruct"是一个"一次性使用"的桥梁,需要锅炉板代码.我正在寻找最简洁的方法,这样我就不必创建中间构造来执行映射.理想情况下,我能够以扩展类或结构的方式扩展协议. (3认同)

Cod*_*ent 5

您可以从A 继承B

protocol A: B { var a: String { get } }
protocol B    { var b: String { get } }

// Default implementation of property b
extension A {
    var b: String { get { return "PropertyB" } }
}


class MyClass: A {
    var a: String { get { return "PropertyA" } }

    func printA(obj: A) {
        print(obj.a)
        printB(obj)
    }

    func printB(obj: B) {
        print(obj.b)
    }
}

let obj = MyClass()
obj.printA(obj)
Run Code Online (Sandbox Code Playgroud)

由于A继承自B,因此中的每个属性B都可用A

  • 这与OP的要求根本不同。如果他没有对“ A”或“ B”的控制,这将不会有太大帮助。 (6认同)
  • 我不想创建额外的协议。 (3认同)
  • 然后您问一个[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) (2认同)