简体   繁体   中英

How to create a protocol with a generic function extending type

I'm trying to do a protocol with a generic function where T is not just equal to the type, but extends it.

class MainItem {}
class Item1: MainItem {}
class Item2: MainItem {}

protocol MyProtocol {
    func myFunc<T: MainItem>() -> T // T extends MainItem
}

class ClassA: MyProtocol {
    func myFunc() -> Item1 { // not MainItem
        return Item1()
    }
}

class ClassB: MyProtocol {
    func myFunc() -> Item2 { // not MainItem
        return Item2()
    }
}

But I get this error

Type 'ClassA' does not conform to protocol 'MyProtocol'

because Item1 is not equal to MainItem (it expands it). How can you make it work?

For example, in Java everything can be done using abstract class:

abstract class MyProtocol {
    abstract <T extends MainItem> T myFunc()
}

Generics is not the way to go for your requirements. When you declare a generic function in a protocol, the generic type parameter will mean that the same function works for all types that satisfy the generic type restriction, but the function signature still needs to be intact for all conforming types.

What you are looking for is a protocol with associated type . An associated type on a protocol means that the conforming type can decide what concrete type to use in place of the associated type, hence allowing you to use different associated types in different conforming classes.

protocol MyProtocol {
    associatedtype MyType: MainItem
    func myFunc() -> MyType
}

class ClassA: MyProtocol {
    func myFunc() -> Item1 {
        return Item1()
    }
}

class ClassB: MyProtocol {
    func myFunc() -> Item2 {
        return Item2()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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