If I change it slightly
protocol JSONDecodable { init() }
protocol CompressedDecodable: JSONDecodable { }
class NetworkRequest<T: JSONDecodable> {
var response: T?
func doAThing() {
response = doSomething()
}
func doSomething<T: JSONDecodable>() -> T {
print("One: \(T.self)")
return T()
}
}
class CompressedNetworkRequest<U: CompressedDecodable>: NetworkRequest<U> {
override func doSomething<U: CompressedDecodable>() -> U {
print("Two: \(U.self)")
return U()
}
}
struct Uno: JSONDecodable { }
struct Dos: CompressedDecodable { }
NetworkRequest<Uno>().doAThing()
CompressedNetworkRequest<Dos>().doAThing()
I do get the output:
One: Uno
Two: Dos
But I also get a crash error: Execution was interrupted, reason: EXC_BAD_ACCESS
(code=EXC_I386_GPFLT).
—
Fred
From: Jon Shier via swift-users <[email protected]>
Reply: Jon Shier <[email protected]>
Date: 16 November 2017 at 05:43:06
To: Седых Александр via swift-users <[email protected]>
Subject: [swift-users] Refining generics in classes
Swift Users:
I have a generics use case which has somewhat stumped me. I have two related
protocols, JSONDecodable and CompressedDecodable, and CompressedDecodable
inherits from JSONDecodable (though that relationship isn’t strictly
necessary). I also have a generic function that’s overloaded for each of those
protocols. I’m trying to write a class to make a network request expecting a
generic response type of either JSONDecodable or CompressedDecodable. However,
it doesn’t seem possible to write it in such a way that the overload I need is
called. Instead, it’s always the superclass’ type’s overload that is called.
For example:
protocol JSONDecodable { init() }
protocol CompressedDecodable: JSONDecodable { }
class NetworkRequest<T: JSONDecodable> {
var response: T?
func doAThing() {
response = doSomething()
}
}
class CompressedNetworkRequest<U: CompressedDecodable>: NetworkRequest<U> {
}
func doSomething<T: JSONDecodable>() -> T {
print("One: \(T.self)")
return T()
}
func doSomething<T: CompressedDecodable>() -> T {
print("Two: \(T.self)")
return T()
}
struct Uno: JSONDecodable { }
struct Dos: CompressedDecodable { }
NetworkRequest<Uno>().doAThing()
CompressedNetworkRequest<Dos>().doAThing()
In a playground this prints:
One: Uno
One: Dos
Ultimately, I understand why this happens (NetworkRequest’s generic type is
always going to be JSONDecodable, no matter if it’s actually a subtype). Is
there any way, aside from completely duplicating the class, to call the
overload appropriate for the type passed in a class like this?
Jon Shier
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users