Reputation: 224
I'm trying to use pass an Enum to a closure, not unlike what Apple does on the guided tour on it's webpage.
This works perfectly fine:
public enum CreateProductResult<A:Product, B:NSError> {
case product(A)
case error(B)
}
public typealias CreateProductHandler = (CreateProductResult <Product, NSError>) -> ()
But this won't compile:
public enum FetchProductResult<A:[Product], B:NSError> {
case product(A)
case error(B)
}
public typealias FetchProductsHandler = (FetchProductResult <[Product], NSError>) -> ()
The Error:
error: expected a type name or protocol composition restricting 'A'
Why is it wrong when I try to pass in an Array
? Do I really have to write a wrapper class around it just to use that as an Enum?
Upvotes: 1
Views: 295
Reputation: 72770
An array is a struct, and swift doesn't support inheritance for structs, so it would make no sense specifying a type that must inherit from an array.
You can fix that by letting the product
case expect an array, and just specify Product
in the generic constraint:
public enum FetchProductResult<A:Product, B:NSError> {
case product([A])
case error(B)
}
public typealias FetchProductsHandler = (FetchProductResult <Product, NSError>) -> ()
Note that your code would work if the array were a reference type - just to prove that, if you create a ReferenceArray
class (for which I am providing an empty implementation), this code works:
public class ReferenceArray<T> {}
public enum FetchProductResult<A:ReferenceArray<Product>, B:NSError> {
case product(A)
case error(B)
}
public typealias FetchProductsHandler = (FetchProductResult <ReferenceArray<Product>, NSError>) -> ()
But wait, a reference type version of the array already exists: NSArray
- you could use it if you prefer, but of course it doesn't support generics:
public enum FetchProductResult<A:NSArray, B:NSError> {
case product(A)
case error(B)
}
public typealias FetchProductsHandler = (FetchProductResult <NSArray, NSError>) -> ()
so actually not an elegant solution to your specific problem.
Upvotes: 2
Reputation: 224
This shouldn't be declared as a generic, since you can't pass a struct (which is what an ``Array``` is in Swift). Instead you have to be more specific:
public enum FetchProductResult{
case product([Product])
case error(NSError)
}
public typealias FetchProductsHandler = (FetchProductResult) -> ()
Upvotes: 0