Agreed. I also think the compiler should warn when you shadow a type parameter. Every single time I've seen a programmer do this this, it's been by mistake and has caused poor diagnostics and general confusion.
to work with before a Swifty solution is provided to replace it.
You don't want to perform dynamic type checking, and cast accordingly. But you also don't want to deal with someone else imposing their opinion on your naming choices.
I'm sure there are plenty of valid use cases that people have come up with. You all are better at this than I am but nobody has the superset of all of our creativity.
public extension Optional {
/// [An alternative to overloading `??` to throw errors upon `nil`.](
/// https://forums.swift.org/t/unwrap-or-throw-make-the-safe-choice-easier/14453/7)
/// - Note: Useful for emulating `break`, with `map`, `forEach`, etc.
/// - Throws: `UnwrapError` when `nil`.
var unwrapped: Wrapped {
get throws {
switch self {
case let wrapped?:
return wrapped
case nil:
throw UnwrapError.nil
}
}
}
/// [An alternative to overloading `??` to throw errors upon `nil`.](
/// https://forums.swift.org/t/unwrap-or-throw-make-the-safe-choice-easier/14453/7)
/// - Note: Useful for emulating `break`, with `map`, `forEach`, etc.
/// - Throws: `UnwrapError`
func unwrap<Wrapped>() throws -> Wrapped {
guard case let wrapped as Wrapped = try unwrapped
else { throw UnwrapError.typeMismatch }
return wrapped
}
}
/// Acts as a dictionary that `throw`s instead of returning optionals.
public protocol DictionaryLike<Key, Value> {
associatedtype Key
associatedtype Value
subscript(key: Key) -> Value? { get }
}
public extension DictionaryLike {
/// `self[key].unwrapped()`
subscript<Value>(key: Key) -> Value {
get throws { try self[key].unwrap() }
}
/// Allows lookup by enumeration cases backed by `Key`s,
/// instead of having to manually use their raw values.
subscript<Value>(key: some RawRepresentable<Key>) -> Value {
get throws { try self[key.rawValue] }
}
}
Yeah, I understood the case and tried to fix it with below code but ended up with few more errors.
protocol ServiceManagerProtocol {
associatedtype T
func requestForDataDownload(fromUrl: URL,
withParameters: [String: Any]?,
outputDataFormat: String,
type: T.Type) -> AnyPublisher<T, AFError>
}
class ServiceManager<T: Decodable>: ServiceManagerProtocol {
func requestForDataDownload(fromUrl: URL,
withParameters: [String: Any]?,
outputDataFormat: String,
type: T.Type) -> AnyPublisher<T, AFError> {
}
}
final class MockServiceManager<T: Decodable>: ServiceManagerProtocol {
var downloadedData: AnyPublisher<T, AFError>?
func requestForDataDownload(fromUrl: URL,
withParameters: [String: Any]?,
outputDataFormat: String,
type: T.Type) -> AnyPublisher<T, AFError> {
if let data = downloadedData {
return data
} else {
fatalError("Data must not be nil.")
}
}
}
class SomeClass: NSObject {
let serviceManager: ServiceManagerProtocol // Error: Use of protocol 'ServiceManagerProtocol' as a type must be written 'any ServiceManagerProtocol'
init(serviceManager: ServiceManagerProtocol = ServiceManager()) { // Error 1: Generic parameter 'T' could not be inferred
// Error 2: Use of protocol 'ServiceManagerProtocol' as a type must be written 'any ServiceManagerProtocol'
self.serviceManager = serviceManager
}
}
But still, I do have one more doubt. What if I need two different types from ServiceManager from the same class where I am initialising it.
Like in this case ServiceManager is a class where I make the network calls and it can return objects of any type. And, the class where I initialise it can make network calls to different APIs which in turn will return data of different types.