Kristof Van Landschoot Kristof Van Landschoot - 7 months ago 30
Swift Question

Trying to generalise in swift

I am trying to create a generalised class in Swift, Xcode 7.3 (so Swift 2.2), but I can not seem to get it past the compiler:

protocol Struct1Protocol {

struct Struct1 {
var name1: String

protocol Struct2Protocol {

struct Struct2: Struct2Protocol {
var name2: String

class StructDependent<T> {
func setupFrom<T:Struct1Protocol>(value: T) {
print("we want to setup StructDependent with struct 1")

func setupFrom<T:Struct2Protocol>(value: T) {
print("we want to setup StructDependent with struct 2")

class A<T> {
func test(value: T) {
let structInstance = StructDependent<T>()
// this gives a compiler error:
// Cannot invoke 'setupFrom' with an argument list of type '(T)'

The idea is to have a
that can be set up from different structs. Class A should be able to call setupFrom if the class has been instantiated with a compatible struct. Like so:

let a = A<Struct1>()
let v = Struct1(name1: "")

How would I go about this? I am a bit blocked here, so all ideas are welcome.


It seems to me that you're way over-thinking this. I would take a much more simple-minded view of the case and do it entirely without generics; instead, we just use a protocol as a kind of supertype of the two structs (just as we would use a superclass if the structs were classes):

protocol StructProtocol {
    var name : String {get set}
    func setup()

struct Struct1 : StructProtocol{
    var name: String
    func setup() {}

struct Struct2 : StructProtocol {
    var name: String
    func setup() {}

class StructDependent {
    func setup(s:StructProtocol) {
        s.setup() // or not, I don't care...
        // or you could just switch on the type, e.g.:
        switch s {
        case is Struct1: // ...
        case is Struct2: // ...
        default: break

class A {
    func test(value: StructProtocol) {
        let structInstance = StructDependent()

If StructDependent itself really needs to do different things depending on what setup is called with, it can switch on the actual type. But it would be better the first way, where we just call something that both Struct1 and Struct2 know how to do, each in its own way.