我想实现一个Swift方法,它接受一个特定的类类型,但只接受符合特定协议的类的实例。例如,在Objective-C中我有这个方法:
- (void)addFilter:(GPUImageOutput<GPUImageInput> *)newFilter;
其中GPUImageOutput是一个特定的类,而GPUImageInput是一个协议。只有符合此协议的GPUImageOutput类才是此方法的可接受输入。
func addFilter(newFilter: GPUImageOutput!)
这消除了GPUImageOutput类符合GPUImageInput协议的要求,这将允许非兼容对象传入(然后在运行时崩溃)。当我尝试将其定义为GPUImageOutput< GPUImageInput> ;,编译器抛出一个错误
Cannot specialize non-generic type ‘GPUImageOutput’
我将如何在Swift的参数中做这样的类和协议专门化?
是swift你必须使用泛型,以这种方式:
给定这些示例协议,主类和子类的声明:
protocol ExampleProtocol { func printTest() // classes that implements this protocol must have this method } // an empty test class class ATestClass { } // a child class that implements the protocol class ATestClassChild : ATestClass,ExampleProtocol { func printTest() { println("hello") } }
现在,您想要定义一个方法,该方法接受符合协议ExampleProtocol的类型为ATestClass(或子)的输入参数。
编写方法声明如下:
func addFilter<T where T: ATestClass,T: ExampleProtocol>(newFilter: T) { println(newFilter) }
你的方法,重新定义在swift,应该是
func addFilter<T where T:GPUImageOutput,T:GPUImageInput>(newFilter:T!) { // ... }
编辑:
作为你的最后一个评论,一个例子与泛型的枚举
enum OptionalValue<T> { case None case Some(T) } var possibleInteger: OptionalValue<Int> = .None possibleInteger = .Some(100)
专业协议一致性:
enum OptionalValue<T where T:GPUImageOutput,T:GPUImageInput> { case None case Some(T) }
EDIT ^ 2:
您可以使用泛型甚至与实例变量:
假设你有一个类和一个实例变量,你希望这个实例变量只接受类型ATestClass的值,并且符合ExampleProtocol
class GiveMeAGeneric<T: ATestClass where T: ExampleProtocol> { var aGenericVar : T? }
然后以这种方式实例化它:
var child = ATestClassChild() let aGen = GiveMeAGeneric<ATestClassChild>() aGen.aGenericVar = child
如果孩子不符合ProtocolProtocol协议,它将不会编译