Using Generic Protocols

I am in a situation where I would love to use protocols with generics in swift, but it seems I can't use these protocols in a convenient way in swift.

My ideal pattern would be something like

protocol Foo {
    associatedtype T
    func foo()
}

class FooUsingClass {
    // I want to do this
    func doSomethingWithFoo(_ foo: Foo<String>) { // Not allowed
        
    }
}

I know I can't use it like func doSomethingWithFoo(_ foo: Foo), and the reason makes sense to me. I am aware of type erasing and have been looking at things like ios - Protocol can only be used as a generic constraint because it has Self or associatedType requirements - Stack Overflow

I don't quite understand why I can't do what I was trying to do above (i.e. func doSomethingWithFoo(_ foo: Foo<String>)). It seems like it should be possible to create a compiler that would be able to handle that. For example, this is valid C#

    private static void printValueInDict(IDictionary<String, String> dict, String key) {
        Console.WriteLine("Dict has " + dict[key]);
    }

I am curious to know why this choice was made and if it would possibly be something that could be added to swift.

Hi Tomas! I think you'll be interested in this proposed language feature that's currently under review: swift-evolution/0346-light-weight-same-type-syntax.md at main · apple/swift-evolution · GitHub

Here's the review thread, in case you're interested in leaving a review: SE-0346: Lightweight same-type requirements for primary associated types

5 Likes

If I understand what you're trying to achieve I believe this should do what you want today.

protocol Foo {
    associatedtype T
    func foo()
}


class FooUsingClass {
    func doSomethingWithFoo<F:Foo>(_ foo: F) where F.T == String {
        foo.foo()
    }
}
7 Likes