[英]Allow Swift function parameter to be of multiple types
一個函數
func stepperValueChanged(_ myStepper: UIStepper) {
// do stuff with myStepper
}
第二個功能
func switchValueChanged(_ mySwitch: UISwitch) {
// do stuff with mySwitch
}
如何創建可以采用任一類型的第三個(替代)函數?
func valueChanged(_ myComponent: /* ??? UIStepper or UISwitch, but nothing else ??? */) {
// do stuff with myComponent
}
我已經探索過使用枚舉、類型別名和協議; 這導致了許多有趣的 Stackoverflow 讀取,但沒有解決方案。
不起作用的例子
// ** DON'T COPY AND PASTE, DONT WORK!! ** //
typealias validUIComponent = UIStepper, UISwitch
// or
typealias validUIComponent = UIStepper & UISwitch
// or
enum UIComponent { case stepper(UIStepper); case _switch(UISwitch) }
// or
protocol UIComponent { }
extension UIStepper: UIComponent { }
extension UISwitch: UIComponent { }
// ** DON'T COPY AND PASTE, DONT WORK!! ** //
我為什么要這樣做? 類型檢查。 我不希望將任何其他 UI 元素傳遞給該函數。
我意識到如果 let/guard let 或某種其他形式的檢查一次在函數體中並根據需要保釋我可以,但這只會捕獲運行時而不是編譯時類型錯誤。
我也意識到我可以使用任何? 或(更好) UIControl 並根據需要向下轉型。
func valueChanged(_ myComponent: UIControl) {
// do stuff with
myComponent as! UIStepper
// do stuff with
myComponent as! UISwitch
}
但是有沒有語法/更具表現力的解決方案?
你提到了枚舉,這聽起來非常適合這個用例。 您可以明確地只要求您期望的類型,而沒有其他要求。 通過向枚舉添加屬性,您可以公開UIControl
屬性以根據需要進行交互,而無需向下轉換(這通常被認為是反模式)。
enum Component {
case `switch`(UISwitch)
case stepper(UIStepper)
var control: UIControl {
switch self {
case .switch(let comp):
return comp
case .stepper(let comp):
return comp
}
}
}
然后請求一個Component
作為函數的參數。
func controlValueChanged(_ myComponent: Component) {
// Now you can use them as a generic UIControl
let control = myComponent.control
// ...or different behaviours for each element
switch myComponent {
case .switch(let swit):
// use the `swit`
case .stepper(let step):
// use the `step`
}
}
話雖如此,如果這些類型的實現無論如何都完全不同,那么定義兩個單獨的函數可能會更清楚。
我認為你在這里把事情復雜化了,並且沒有必要通過引入協議或新類型(枚舉)來創建任何開銷。
相反,我會通過使用多態並聲明多個具有相同簽名的函數來處理這個問題。
func controlValueChanged(_ switch: UISwitch) {
// code…
}
func controlValueChanged(_ stepper: UIStepper) {
// code…
}
這將使調用代碼保持整潔,並使每個函數的責任清晰。
如果兩個函數之間有一些公共代碼,則將其提取到第三個公共函數中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.