litebrite
litebrite

Reputation: 175

Swift error: Generic parameter 'T' is not used in function signature

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

Answers (3)

Chinh Nguyen
Chinh Nguyen

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

vadian
vadian

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

0x416e746f6e
0x416e746f6e

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

Related Questions