如何指定非泛型 Swift 类型应遵守协议? [英] How do I specify that a non-generic Swift type should comply to a protocol?

查看:40
本文介绍了如何指定非泛型 Swift 类型应遵守协议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个 Swift 方法,该方法接受某种类类型,但只接受符合特定协议的那些类的实例.例如,在 Objective-C 中我有这个方法:

I'd like to implement a Swift method that takes in a certain class type, but only takes instances of those classes that comply to a specific protocol. For example, in Objective-C I have this method:

- (void)addFilter:(GPUImageOutput<GPUImageInput> *)newFilter;

其中 GPUImageOutput 是一个特定的类,而 GPUImageInput 是一个协议.只有符合此协议的 GPUImageOutput 类才是此方法可接受的输入.

where GPUImageOutput is a particular class, and GPUImageInput is a protocol. Only GPUImageOutput classes that comply to this protocol are acceptable inputs for this method.

然而,上面自动生成的Swift版本是

However, the automatic Swift-generated version of the above is

func addFilter(newFilter: GPUImageOutput!)

这消除了 GPUImageOutput 类遵守 GPUImageInput 协议的要求,这将允许传入不合规的对象(然后在运行时崩溃).当我尝试将其定义为 GPUImageOutput 时,编译器会抛出

This removes the requirement that GPUImageOutput classes comply with the GPUImageInput protocol, which will allow non-compliant objects to be passed in (and then crash at runtime). When I attempt to define this as GPUImageOutput<GPUImageInput>, the compiler throws an error of

不能特化非泛型类型 'GPUImageOutput'

Cannot specialize non-generic type 'GPUImageOutput'

我将如何在 Swift 中的参数中进行这样的类和协议特化?

How would I do such a class and protocol specialization in a parameter in Swift?

推荐答案

你必须快速使用泛型,这样:

Is swift you must use generics, in this way:

给定这些协议、主类和子类的示例声明:

Given these example declarations of protocol, main class and subclass:

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(或子项)类型的输入参数.像这样编写方法声明:

Now, you want to define a method that takes an input parameters of type ATestClass (or a child) that conforms to the protocol ExampleProtocol. Write the method declaration like this:

func addFilter<T where T: ATestClass, T: ExampleProtocol>(newFilter: T)
{
    println(newFilter)
}

你的方法,在 swift 中重新定义,应该是

Your method, redefined in swift, should be

func addFilter<T where T:GPUImageOutput, T:GPUImageInput>(newFilter:T!)
{
    // ...
}

作为你最后的评论,一个关于枚举的泛型示例

as your last comment, an example with generics on an Enum

    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)
    }

编辑^2:

您甚至可以使用实例变量使用泛型:

you can use generics even with instance variables:

假设你有一个类和一个实例变量,你希望这个实例变量只接受 ATestClass 类型的值并且符合 ExampleProtocol

Let's say you have a class and an instance variable, you want that this instance variable takes only values of the type ATestClass and that conforms to ExampleProtocol

class GiveMeAGeneric<T: ATestClass where T: ExampleProtocol>
{
    var aGenericVar : T?
}

然后这样实例化:

    var child = ATestClassChild()
    let aGen = GiveMeAGeneric<ATestClassChild>()
    aGen.aGenericVar = child

如果child不符合ExampleProtocol协议,则不会编译

If child doesn't conform to the protocol ExampleProtocol, it won't compile

这篇关于如何指定非泛型 Swift 类型应遵守协议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆