我想实现只接受类支持的协议的方法。为此,我定义了一个协议:

protocol TestProt {
    func testMe() -> String
}

我们来做一个类声明:
class TestClass: TestProt {
    func testMe() -> String {
        return "test"
    }
}

但是,我如何实现register类,只有类支持testprot?
class FabricaClass {
    // it is func take any classes :(
    func registerMe(context: MyContext, class: AnyClass) -> String {
    }
    // i want something like this =)
    // to the method took only classes supported protocols
    // but it don't work for swift...
    func registerMe(context: MyContext, class: AnyClass <TestProt>) -> String {
    }

}

UPD:回答
protocol TestProt {
    static func testMe() -> String
}

class TestClass: TestProt {
    class func testMe() -> String {
        return "test"
    }
}

class MyContext {
}

class FactoryClass {
    init<T: TestProt>(context: MyContext, regClass: T.Type) {
        regClass.testMe()
    }
}

let context = MyContext()
let factory = FactoryClass(context: context, regClass: TestClass.self)

感谢您@dfri

最佳答案

您需要在函数中包含泛型类型,并为此泛型类型添加类型约束,其中类型约束确保使用函数的类型符合用作类型约束的协议。例如。:

/* add :class keyword to constrain this protocol only
 to be conformable to by class types */
protocol ProtocolOnlyIntendedForClasses: class {
    func foo() -> String
    init() // to make use of metaType for initialization in generic function
}

class Foo: ProtocolOnlyIntendedForClasses {
    func foo() -> String {
        return "foo"
    }
    required init() { }
}

/* function taking class type objects that conforms
   to ProtocolOnlyIntendedForClasses */
func bar<T: ProtocolOnlyIntendedForClasses>(foo: T) -> String {
    return foo.foo()
}

/* as above, but making use of metatype representation
   of generic T rather than an instance of it */
func barWithMetaType<T: ProtocolOnlyIntendedForClasses>(fooMetaType: T.Type) -> String {

    // ..

    return fooMetaType.init().foo()
}

/* example usage */
let foo = Foo()
let baz = bar(foo)
let bax = barWithMetaType(Foo.self)
print(baz, bax) // foo foo

在这里,我们使用TT.Type类型作为元类型访问。
应用于您的特定示例:
// ...

class FabricaClass {

    // ...

    // as specified in comments, you want the class (meta)type,
    // rather than an instance of it
    func registerMe<T: TestProt>(context: MyContext, someMetaType: T.Type) -> String {

        // ...

        return someMetaType.init().testMe()
            // given that you added blueprint for 'init()' in protocol TestProt
    }

}

但是,请注意,use元类型(someMetaType在上面的registerMe(..)函数中)非常有限,并不等同于使用静态(编译时已知)类型。
有关其他详细信息,请参阅
The Language Guide - Generics: Section Type Constraints
The Language Guide - Protocols
The Language Reference - Types: Section Metatypes

关于swift - Swift:仅限制类支持的协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36480731/

10-14 22:43
查看更多