Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Inherit from Generic Type

Tags:

generics

swift

I'm trying to inherit from a generic type, so that I can insert a type into a hierarchy:

class Foo < T:AnyObject > : T {}

but I get error

inheritance from non-protocol, non-class type 'T'

but I'm ensuring T is a class (even if I change AnyObject to some other class). Is this just not possible?

like image 404
zacaj Avatar asked Dec 16 '14 15:12

zacaj


1 Answers

Isn't CRTP (Curiously recurring template pattern) different than in the OP anyways?

It's totally fine to design that pattern in Swift (<= 3.0), but it's currently bugged and will lock on initialization without any error during runtime.

class Template<T> { ... }

class RealThing : Template<RealThing> { ... }

I recently discovered this pattern in bridged UIKit API. You can read that in my short blog post here.

I also translated the example from wiki into Swift 3.0:

protocol Constructor {
    init()
}

protocol Shape {
    func cloned() -> Shape
}

typealias ShapeProtocols = Constructor & Shape

class Shape_CRTP<T> : ShapeProtocols {

    required init() {}

    func  cloned() -> Shape {
        let new = Shape_CRTP<T>()
        // copy everything to `new` from `self`
        return new
    }
}

extension Shape_CRTP where T : ShapeProtocols {

    func cloned() -> Shape {
        let new = T()
        // copy everything to `new` from `self`
        return new
    }
}

// First non-crtp proof of concept
class Square : ShapeProtocols {

    required init() {}
    func cloned() -> Shape {
        return Square()
    }
}

let clone = Shape_CRTP<Square>().cloned() // creates a new `Shape`
type(of: clone) // Square.Type

// now CRTP but this is bugged: http://blog.devandartist.com/posts/swift-crtp
class Circle : Shape_CRTP<Circle> {}

Circle().cloned()

print("this will never print because of the described bug")
like image 193
DevAndArtist Avatar answered Oct 10 '22 16:10

DevAndArtist