Reputation: 6662
I'd like to extract the type from an array passed as a parameter to a function, as to have the type parameter optional.
init(type: ContentType? = nil, style: LayoutStyle, content: [ContentProtocol]) {
self.type = type ?? {
switch content {
case is [Ad]: return .ads
case is [User]: return .users
case is [List]: return .list
default: fatalError("Can't assume.")
}
}()
}
Ad
, User
and List
all conform to ContentProtocol
.
These switch statements cause an error, "Optional type '[Ad/User/List]' cannot be used as a boolean; test for '!= nil' instead"
which is not what I want to do.
This init however, does work.
init(type: ContentType? = nil, style: LayoutStyle, fetcher: ContentFetcher) {
self.type = type ?? {
switch fetcher {
case is AdFetcher: return .ads
case is UserFetcher: return .users
case is ListFetcher: return .list
default: fatalError("Can't assume.")
}
}()
}
ContentFetcher
is another protocol, and all the types in the switch statement conforms to this.
Can I achieve the same as the last init with the first init?
Upvotes: 0
Views: 105
Reputation: 17534
protocol P{}
struct A: P{}
struct B: P{}
struct C: P{}
let a = [A(), A()]
let b = [B(), B()]
let c = [C(), C()]
func foo(arr: [P]) {
if let a = arr as? [A] {
print(1, "A", a, type(of: a))
} else if let b = arr as? [B] {
print(1, "B", b, type(of: b))
} else {
print("not A nor B")
}
switch arr {
case let a where a is [A]:
print(2, "A", a, type(of: a))
case let b where b is [B]:
print(2, "B", b, type(of: b))
default:
print("not A nor B")
}
print()
}
foo(arr: a)
foo(arr: b)
foo(arr: c)
prints
1 A [__lldb_expr_245.A(), __lldb_expr_245.A()] Array<A>
2 A [__lldb_expr_245.A(), __lldb_expr_245.A()] Array<P>
1 B [__lldb_expr_245.B(), __lldb_expr_245.B()] Array<B>
2 B [__lldb_expr_245.B(), __lldb_expr_245.B()] Array<P>
not A nor B
not A nor B
if the input array is
let d:[P] = [A(), B()]
it prints
not A nor B
not A nor B
as expected
Upvotes: 0