简体   繁体   English

协议的泛型

[英]Generics on protocol

I have this protocol: 我有这个协议:

protocol Addable
{
    mutating func addNumber(value: Int)
}

and this extension 和这个扩展

extension Int : Addable
{
    mutating func addNumber(value: Int)
    {
        self = self + value
    }
}

This code: 这段代码:

    var number : Int = 10
    number.addNumber(10)
    println(number)

Correctly prints 20 正确打印20

Now I want to extend the protocol Addable to other types. 现在我想将协议Addable扩展到其他类型。 If I understand correctly, I don't use Generics with protocol, but I use an associated type: 如果我理解正确,我不使用泛型与协议,但我使用相关的类型:

protocol Addable
{
    typealias AddableType
    mutating func addNumber(value: AddableType)
}

So now, AddableType means a generic type, and I can extend for example Float 所以现在, AddableType意味着一个泛型类型,我可以扩展例如Float

extension Float : Addable
{
    mutating func addNumber(value: Float)
    {
        self = self + value
    }
}

    var another : Float = 10.5
    another.addNumber(10.1)
    println(another)

This prints 20.6 这打印20.6

Now, I know that I can enforce the associated type to conform to a protocol 现在,我知道我可以强制执行相关类型以符合协议

protocol Addable
{
    typealias AddableType : AProtocol, AnotherProtocol // ...
    mutating func addNumber(value: AddableType)
}

But, and here it's the question, I cannot enforce the conformance to a Type or some types 但是,这就是问题,我不能强制执行类型或某些类型的一致性

protocol Addable
{
    typealias AddableType : Int, Float
    mutating func addNumber(value: AddableType)
}

Error: Inheritance from non-protocol, non-class type 'Int'
Error: Inheritance from non-protocol, non-class type 'Float'

Is there any possibility to do this? 有没有可能这样做?

You can create a second protocol and implement that on the types that you want: 您可以创建第二个协议并在您想要的类型上实现它:

protocol AddableRequirement {}

extension Int: AddableRequirement {}
extension Float: AddableRequirement {}

protocol Addable {
    typealias AddableType: AddableRequirement
    mutating func addNumber(value: AddableType)
}

You also may want to use Self instead of a typealias: 您也可能想要使用Self而不是typealias:

protocol Addable {
    mutating func addNumber(value: Self)
}

That way, your protocol requires that the type always be addable with itself. 这样,您的协议要求该类型始终可以自行添加。

You could define a new protocol and declare conformance for the types you want to allow. 您可以定义新协议并声明要允许的类型的一致性。

protocol AllowedAddableType {}

extension Int: AllowedAddableType {}
extension Float: AllowedAddableType {}
// ...

protocol Addable
{
    typealias AddableType: AllowedAddableType
    mutating func addNumber(value: AddableType)
}

Types can conform to protocols, and protocols can conform to protocols, but protocols cannot conform to types. 类型可以符合协议,协议可以符合协议,但协议不符合类型。 Having a protocol conform to a type doesn't make any sense within the grammatical definition of the language. 使协议符合类型在语言的语法定义中没有任何意义。

I'm guessing that your intention is to limit the types of objects that are allowed to conform to this protocol. 我猜你的目的是限制允许符合这个协议的对象类型。 In that case, you can define a protocol that inherits from a type, and then have your protocol conform to that protocol. 在这种情况下,您可以定义一个从类型继承的协议,然后使您的协议符合该协议。

protocol TypeRestrictor {}

extension Int: TypeRestrictor {}
extension Float: TypeRestrictor {}

protocol Addable {
    typealias AddableType: TypeRestrictor
    mutating func addNumber(value: AddableType)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM