In Java you can some times use generics without caring about the actual type. Can you do that in Swift?
For instance MyClass<AnyObject>
doesn't work like MyClass<?>
would in Java. At I'd expect it to work the same.
Is there any other way?
Introduce a type parameter; the compiler will let it take any type. Try:
func executeRequest<T> (request: APIRequest<T>) {
// ...
}
For example:
class APIRequest<T> {}
class Movie {}
class MovieRequest : APIRequest<Movie> {}
let m = MovieRequest()
//print(m)
func executeRequest<T> (request: APIRequest<T>) {
print(request)
}
executeRequest(m)
The introduction of a type parameter allows one to be more explicit and to better match the problem domain. For example, in your case, you surely can't do a APIRequest
on anything whatsoever; you can make an APIRequest
on, say, a Resource
.
protocol Resource {}
class Movie : Resource {}
class Song : Resource {}
class APIRequest<T:Resource> { /* ... */ }
func executeRequest<T:Resource> (request: APIRequest<T>) { /* ... */ }
There is no equivalent in Swift. Generics in Swift are somewhat different from in Java generally, so the use cases are different, too. Generics in Swift are very good for making general utility constructs and functions. If you are considering designing classes with intended inheritance around Generics, be very careful up front with your design up front and consider alternatives. It may be quite challenging. There are fundamental differences in the two languages, so trying to maintain parities in code may prove difficult. Some requirements will result in fundamentally different solutions in the two languages.
Here are some possible options depending on the specifics of your problem:
// start with a common protocol
protocol Requestable {
func execute()
func processData(input: Any)
}
// protocol with type constraint
protocol APIRequest : Requestable {
typealias ContentType
var content : ContentType { get }
func processInput(input: ContentType)
}
extension APIRequest {
func processData(input: Any) {
if let input = input as? ContentType {
processInput(input)
} else {
// probably should throw an error here
}
}
}
// Either define a Generic function to execute with a specific type
func executeRequest<RequestType:APIRequest>(request: RequestType) {
request.execute()
}
// Or define a function taking a protocol conforming type
func executeRequest(request: Requestable) {
request.execute()
}
// process the data with a specific request and input
func processRequest<RequestType:APIRequest>(request: RequestType, input: RequestType.ContentType) {
request.processInput(input)
}
// process the data with input of arbitrary type
func processRequest(request: Requestable, data: Any) {
request.processData(data)
}
class Movie {
}
class MovieRequest : APIRequest {
var content : Movie
init(movie: Movie) {
self.content = movie
}
func execute() {
// do something here
}
func processInput(input: Movie) {
// do something with the movie input
}
}
let movieRequest = MovieRequest(movie: Movie())
executeRequest(movieRequest)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With