Reputation: 35
I'm new to generics and I want to apply it for this logic.
So I have created an enum of user types. I have a userModel object that contains this user type information.
Now my UIViewController A will contain a user object and a tableView. Based on the user type, the number of cells and the cell design will also change.
Basically I don't want to clutter the entire logic into cell ForRowAtIndexPath and other such methods, which is why I was looking into generics.
This is my code
enum UserType : Int {
case None = 0, Musician, Listener
}
class User {
var userType : UserType = .None
}
class A<T:User>: UIViewController {
var selectedUser: T?
}
extension A where T.userType : UserType.Musician
{
func foo() { print("Musician") }
}
This gives me an error
Playground execution failed:
error: MyPlayground.playground:13:53: error: enum element 'Musician' is not a member type of 'UserType'
extension A where T.userType : UserType.Musician {
I would like to know why this error is comming and if my approach is wrong.
Upvotes: 0
Views: 1169
Reputation: 1980
To create extension
you must provide only information known at compile time. userType
is property of User
and hence it's runtime information. It can't be used to create extension
.
But I think you still might benefit from protocols and generics. I'm not sure if it suits you, but anyway here's how it can be done.
You can declare protocols for each type of user like this
protocol UserProtocol {
var userType: UserType { get }
func doYourThing()
}
protocol MusicianProtocol: UserProtocol {}
protocol ListenerProtocol: UserProtocol {}
and create default implementation of UserProtocol
extension UserProtocol where Self: MusicianProtocol {
var userType: UserType { return .musician }
func doYourThing() {
print("Do-di-do!")
}
}
extension UserProtocol where Self: ListenerProtocol {
var userType: UserType { return .listener }
func doYourThing() {
print("Anything except vynil is garbage!")
}
}
Of course this way you will need separate class for each user
class Musician: MusicianProtocol {}
class Listener: ListenerProtocol {}
but generic handling is still possible by using UserProtocol
func letsPlay(_ users: UserProtocol...) {
for u in users {
u.doYourThing()
}
}
let m = Musician()
let l = Listener()
letsPlay(m, l)
Upvotes: 2