Alex Zielenski
Alex Zielenski

Reputation: 3601

Generic in subscript for swift

I understand that with Swift you can specify a function-specific generic with this form:

func someFunction<T>(type: T.Type) {...}

However, is it possible to do something similar with subscripts? Where you can specify a type within the brackets like so:

subscript<T>(type: T.Type) -> T {...}

EDIT: Updated solution based upon the accepted answer

subscript(type: AnyClass.Type) -> Any {
    return sizeof(type)
}

EDIT 2: Upon testing, It seems that I cannot actually use this subscript. I get "CLASS is not identical to AnyClass.Type" so I am back to square one

Upvotes: 15

Views: 6285

Answers (4)

Nhat Dinh
Nhat Dinh

Reputation: 3447

Generic Subscript is supported from Swift 4.0

struct GenericDictionary<Key: Hashable, Value> {
  private var data: [Key: Value]

  init(data: [Key: Value]) {
    self.data = data
  }

  subscript<T>(key: Key) -> T? {
    return data[key] as? T
  }
}

// Dictionary of type: [String: Any]
var earthData = GenericDictionary(data: ["name": "Earth", "population": 7500000000, "moons": 1])

// Automatically infers return type without "as? String"
let name: String? = earthData["name"]

// Automatically infers return type without "as? Int"
let population: Int? = earthData["population"]

For reference

Upvotes: 2

Joe
Joe

Reputation: 3761

Generic subscripts are now available in Swift 4: SE-0148

Upvotes: 7

Mike S
Mike S

Reputation: 42335

You can't define a subscript as a generic function, but you can use a generic type if it's declared at the class level.

For instance, lets say you want to make a class where the subscript takes a type T and returns a type U. That would look something like:

class SomeClass<T, U> {
    subscript(someParameter: T) -> U {
        /* something that returns U */
    }
}

For example, you could create a Converter class that used the subscript function to convert from type T to type U:

Note: This is a very contrived example, I wouldn't normally do this this way.

class Converter<T, U> {
    var _converter: (T -> U)

    init(converter: (T -> U)) {
        _converter = converter
    }

    subscript(input: T) -> U {
        let output = _converter(input)
        return output
    }
}

var convert = Converter(converter: {
    (input: Int) -> String in
    return "The number is: \(input)"
})

let s = convert[1]
println(s) // The number is: 1

Upvotes: 9

return true
return true

Reputation: 7916

I don't think this is possible. Instead you could use Any or AnyObject, and cast the result of the function back to your specified type.

subscript(type: AnyObject) -> AnyObject {
    ...
}

Tip: Instead of type: T.Type, use type: T.

Upvotes: 0

Related Questions