Please consider this setup:
protocol MyProcotol {
}
class MyModel: MyProcotol {
}
enum Result<T> {
case success(value: T)
case failure
}
class Test {
func test<T: MyProcotol>(completion: (Result<T>) -> Void) {
let model = MyModel()
let result = Result.success(value: model)
completion(result)
}
}
Why can't I call completion(result)
? I'm getting this error:
Cannot convert value of type 'Result' to expected argument type 'Result<_>'
Any workaround?
Swift optional variables make code safer if you forget to give an initial value to a variable. The swift optional variable can have a value or be nil if have no value. But in real programming, we need to get the original value that is wrapped by the optional variable.
You can declare a swift variable as a variable ( var name: String = "jerry ") that value can be changed in code, a constant ( let x:Int = Int (10) ) that value can not be changed, and an optional variable ( var x:Int? ) that value can be changed and does not need to be initialized.
@Hamish From the swift docs: "The placeholder type name doesn’t say anything about what T must be, but it does say that both a and b must be of the same type T, whatever T represents". So, when we say [T], it must be an array of all the same types. I absolutely agree.
When you want to unwrap an optional variable that does not has a value that means the variable value is nil, if you use force unwrap in this case, you will encounter an error like below. // Declare an optional variable, the variable do not has value then it's value is nil.
You are using a non-generic concrete type MyModel
in a generic function, that doesn't work.
You could do something like this
class Test {
func test<T: MyProcotol>(item: T, completion: (Result<T>) -> Void) {
let result : Result<T> = .success(value: item)
completion(result)
}
}
You can convert your potential generic value with force cast.
protocol MyProcotol {}
struct MyModel: MyProcotol {
let x: Int
}
struct TheirModel: MyProcotol {
let y: Int
}
enum Result<T> {
case success(value: T)
case failure
var value: T? {
switch self {
case .success(let value): return value
case .failure: return nil
}
}
}
struct Test {
enum ModelType {
case my, their
}
static func get<T: MyProcotol>(type: ModelType, completion: (Result<T>) -> Void) {
let model: Any
switch type {
case .my: model = MyModel(x: 42)
case .their: model = TheirModel(y: 19)
}
if let value = model as? T { completion(.success(value: value)) }
else { completion(.failure) }
}
}
Test.get(type: .my) { (result: Result<MyModel>) in
guard let value = result.value else { return }
print("here is MyModel \(value) with value: \(value.x)")
}
Test.get(type: .their) { (result: Result<TheirModel>) in
guard let value = result.value else { return }
print("here is TheirModel \(value) with value: \(value.y)")
}
Test.get(type: .their) { (value: Result<MyModel>) in
print("here is failure? \(value)")
}
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