У меня есть два вопроса, касающихся Generics a) Я хочу сделать функцию расширения, где мой Result
класс в случае Success
принимает Generi c типа T, однако я получаю следующую ошибку: Use of undeclared type 'T'
Вот мой код:
extension Result<T> where Success == [T] {
/// Function extension for the .success case on a Result object. The result of the Result object are
/// multiple object, in case a list or an iterable in being wrapped.
/// - Parameter callback: Function that the will be executed when the .success case is triggered
func onSuccess(callback: ([T]) -> Void) {
switch self {
case .success(let results):
callback(results)
default:
return
}
}
}
, также касающийся той же проблемы, я хочу, чтобы UIViewController принял массив типа Generi c::
class UIObservableTableViewController: UITableViewController, LifecycleOwner {
func addLiveData<T>(_ liveData: LiveData<T>) {
liveDataObservers.append(liveData)
}
private lazy var liveDataObservers = [LiveData<T>]()
Однако я получаю ту же ошибку, что и предыдущая, как я могу реализовать T вместо Any, или я могу привести T к Any или наоборот?
Я также попробовал следующий код :
extension Result where Success == Collection {
/// Function extension for the .success case on a Result object. The result of the Result object are
/// multiple object, in case a list or an iterable in being wrapped.
/// - Parameter callback: Function that the will be executed when the .success case is triggered
func onSuccess(callback: (Success) -> Void) {
switch self {
case .success(let results):
callback(results)
default:
return
}
}
}
Однако я получаю следующую ошибку компиляции: Protocol 'Collection' can only be used as a generic constraint because it has Self or associated type requirements
LiveData - это следующий класс:
/// Class for implementing the Observable Pattern. This is a Mutable Observable (it can change its value)
class LiveData<T> {
private (set) var value: T
private var valueChanged: ((T) -> Void)?
init(value: T) {
self.value = value
}
/// Function that sets a value on a main thread. This could throw an error is the setValue is not called inside the Main Thread
/// - Parameter value: T object
fileprivate func setValue(value: T) {
print("The value is of type: \(value)")
try! assertMainThread(methodName: "setValue")
self.value = value
valueChanged?(self.value)
}
/// Function that sets a value on a background thread. This could throw an error is the setValue is not called inside the Main Thread
/// - Parameter value: T object
fileprivate func postValue(value: T) {
DispatchQueue.main.async {
self.value = value
self.valueChanged?(self.value)
}
}
/// Function that checks if the current thread is the MainThread
private func assertMainThread(methodName: String) throws {
if !Thread.isMainThread {
throw CustomError("\(methodName) is not in the main thread")
}
}
/// Add closure as an observer and trigger the closure imeediately if fireNow = true
func observe(owner: LifecycleOwner, _ onChange: ((T) -> Void)?) {
valueChanged = onChange
onChange?(value)
// Add the live data into its LifecycleOwner
owner.addLiveData(self)
}
func removeObserver() {
valueChanged = nil
}
}
/// Class for implementing the Observable Pattern. This is a Mutable Observable (it can change its value)
class MutableLiveData<T>: LiveData<T> {
override func setValue(value: T) {
super.setValue(value: value)
}
override init(value: T) {
super.init(value: value)
}
override func postValue(value: T) {
super.postValue(value: value)
}
}