Swift中UI元素通用getText()函数与冗余代码优化问题
哈哈,这种重复写几乎一模一样代码的痛苦我太懂了!不管是文本控件的text取值,还是数值类型的来回转换,重复代码不仅写着烦,后续维护也容易出问题。下面给你两个针对性的优化方案,都是Swift里抽象复用的常用技巧:
一、优化文本控件的重复扩展
UILabel、UITextField、UITextView都有一个可选的text属性,我们可以用协议扩展把重复的getText()逻辑抽离出来:
首先定义一个协议,要求实现者具备可选的text属性:
protocol TextHolder { var text: String? { get } }
然后让需要的控件遵守这个协议(这一步只是声明,不需要写额外代码):
extension UILabel: TextHolder {} extension UITextField: TextHolder {} extension UITextView: TextHolder {}
最后给协议扩展添加默认实现,所有遵守协议的类型都会自动拥有这个方法:
extension TextHolder { func getText() -> String { text ?? "" } // 还能顺便加些通用的辅助方法,比如判断文本是否为空 func isTextEmpty() -> Bool { getText().isEmpty } }
这样以后不管是系统控件还是你自定义的文本类控件,只要遵守TextHolder协议,就能直接用getText(),不用再重复写扩展了。
二、优化数值类型的重复转换代码
Int、Double、Float这类数值类型的相互转换,我们可以用泛型或者协议扩展来统一处理,避免写一堆Int(doubleValue)、Double(intValue)这种重复代码。
方案1:泛型函数
写一个通用的转换函数,支持任意数值类型之间的转换:
func numericConvert<T: Numeric, U: Numeric>(_ value: U) -> T? { // 使用T(exactly:)是安全转换,避免溢出;如果要强制转换可以换成T(value) T(exactly: value) }
使用起来非常简洁:
let intNum = 100 let doubleNum: Double? = numericConvert(intNum) let floatNum: Float? = numericConvert(doubleNum ?? 0.0)
方案2:协议扩展
如果习惯用方法调用的形式,也可以定义一个协议,给所有数值类型添加转换方法:
protocol NumericConvertible { func convertTo<T: Numeric>() -> T? } // 给各个数值类型添加实现 extension Int: NumericConvertible { func convertTo<T: Numeric>() -> T? { T(exactly: self) } } extension Double: NumericConvertible { func convertTo<T: Numeric>() -> T? { T(exactly: self) } } extension Float: NumericConvertible { func convertTo<T: Numeric>() -> T? { T(exactly: self) } }
调用的时候就像这样:
let doubleVal = 3.14 let intVal: Int? = doubleVal.convertTo()
总结
这两种场景的核心优化思路都是抽象重复逻辑:用协议扩展统一处理具有相同属性/行为的类型,用泛型处理类型不确定的通用操作。这样不仅减少了重复代码,后续要修改逻辑(比如把默认空字符串改成"暂无内容",或者调整数值转换的溢出策略),只需要改一处就行,维护成本低很多。
内容的提问来源于stack exchange,提问作者kuzdu
相关产品推荐
相关产品推荐

