Reputation: 175
I'm trying to use generics to simplify some XML deserialization, however, Swift 2.0 is choking saying that I'm not using the generic in my method signature. I'm confused as to why it is throwing this error since I'm directly instantiating the class type passed in. Any suggestions as to the cause of this error? The exact error is:
Generic parameter 'T' is not used in function signature
MTXMLDeserializable is the base class I'm using and has the method: init(properties: Dictionary<String, String>?, propertyMap: Dictionary<String, String>?)
Here is the offending method:
func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [MTXMLDeserializable]? {
if let data = responseData {
let properties = data["body"].children
return properties.map {
(xmlProps) -> MTXMLDeserializable in
let objProps = xmlProps.element!.attributes
return (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
}
} else {
return .None
}
Thinking that it may be choking on using the generic inside of the closure passed to properties.map
I rewrote the method like so:
func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [MTXMLDeserializable]? {
if let data = responseData {
let properties = data["body"].children
let objs = NSMutableArray()
for xmlProps in properties {
let objProps = xmlProps.element!.attributes
let obj = (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
objs.addObject(obj)
}
return objs as! NSArray
} else {
return .None
}
Even switching from (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
to just using T(properties: objProps, propertyMap: self.propertyMap)
doesn't fix the issue.
I've done battle with the swift compiler over this and upgraded to Swift 2.0 hoping I can get around this issue with limited success (in Swift 1.2 it crashed the compiler, at least now it throws an error instead).
I could have subclasses of this class pass their own closure for instantiating the type they are expecting and ditch using a generic for this, but I think this is nice and clean and saves writing all those overridden methods.
Thanks for taking a look and any help is appreciated!
Upvotes: 11
Views: 24314
Reputation: 653
It's a bit dirty but this works for me
func load<T: BaseModel>(rev id: String) -> (String, T?) {
return ("whatever", nil)
}
Upvotes: 6
Reputation: 285082
The error Generic parameter 'T' is not used in function signature means that at least one type in the method signature must be of that generic type, for example
func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?, someOtherParameter : T) -> [MTXMLDeserializable]? {
}
Upvotes: 9
Reputation: 10136
You use generic T
but you do not use it anywhere in the method body. That's what the error is about.
E.g. it probably should look like:
func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [T]? {
if let data = responseData {
let properties = data["body"].children
return properties.map {
(xmlProps) -> T in
let objProps = xmlProps.element!.attributes
return (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
}
} else {
return .None
}
Upvotes: 15