Swift 没有强制解包的通用 downcast

Swift generic without force unwrap downcast

我尝试创建一些基于通用的代码:

protocol ViewModelsCreator {
    associatedtype T: EditItemViewModelType
    func editItemViewModel<T>() -> T
}

class PlacesListViewModel: ViewModelsCreator {
    typealias T = EditPlaceViewModel
    func editItemViewModel<T>() -> T {
        return EditPlaceViewModel()
    }
}

class EditPlaceViewModel: EditItemViewModelType {}

protocol EditItemViewModelType {}

游乐场显示错误:

cannot convert return expression of type 'EditPlaceViewModel' to return type 'T'

并建议使用

return EditPlaceViewModel() as! T

是否有任何解决方案可以避免这种 (as!T) 强制解包代码?我认为编译器应该弄清楚 EditPlaceViewModel 是 EditItemViewModelType 并且应该满足这个泛型。

您需要删除 ViewModelsCreator 协议中的 <T>PlacesListViewModel class.

protocol ViewModelsCreator {
    associatedtype T: EditItemViewModelType
    func editItemViewModel() -> T
}

class PlacesListViewModel: ViewModelsCreator {
    typealias T = EditPlaceViewModel
    func editItemViewModel() -> T {
        return EditPlaceViewModel()
    }
}

您还可以删除类型别名,并在 PlacesListViewModel class 中将 -> T 替换为 -> EditPlaceViewModel。这两种方式都有效,但这更明确。

class PlacesListViewModel: ViewModelsCreator {
    func editItemViewModel() -> EditPlaceViewModel {
        return EditPlaceViewModel()
    }
}