我最近在 ENUMS 中遇到了一些不规则的问题,想知道将外部类中的函数作为ENUM函数中的值(不是原始值)是否安全/允许值)。这是一个示例:
enum pageData: Int {
case page1
case page2
case page3
static let pageGroup = [page1, page2, page3]
func initPage(caption: String = "") -> myCustomType {
var mctData: myCustomType!
switch self {
case .page1:
let text = (caption.isEmpty) ? extClass.getCaptionFunc("page1") : caption
mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
case .page2:
let text = (caption.isEmpty) ? extClass.getCaptionFunc("page2") : caption
mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/03"))
default: ()
}
return mctData
}
}
在 ENUM 中的 SWITCH案例中调用了两个单独的示例函数(extClass.getCaptionFunc()和extClass.formatDateFunc())。 strong>填充 ENUM 函数 initPage()返回的必需数据。
问:这是一个安全/允许的设计吗?到目前为止,测试尚无定论,当枚举和开关盒太大时,应用程序将崩溃,但在较小的占用空间下可以正常工作。
谢谢您的反馈。
答案 0 :(得分:1)
“安全”是什么意思?您的代码包含不正确的语法。
请勿使用强制展开的值myCustomType!
。
使用正确的大小写> :String
的字符串值映射
为pageGroup
使用完全切换
enum pageData: String { case page1 case page2 case page3 static let pageGroup: pageData = [.page1, .page2, .page3] func initPage(caption: String = "") -> myCustomType { var mctData: myCustomType switch self { case .page1: let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01")) case .page2: let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/03")) case .page3: let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01")) } return mctData } }
您的问题是什么?在这种情况下,这种方法与计算变量没有区别。 extClass.getCaptionFunc
没问题。
答案 1 :(得分:1)
以下是根据上述评论建议的重构。如果枚举值与getCaptionFunc返回的标题或formatDateFunc的日期之间存在某种固定的关系,则可以考虑是否应在枚举中实现这些功能,但在不确定您的意图的情况下,我不确定(例如,如果page1应该除非被覆盖,否则始终将其标题设为“第1页”,然后考虑为枚举提供与通过switch self相等的字符串属性)。如果是这样,那么也许extClass.initPage完全没有必要,您可以为myCustomType提供一个带有枚举参数的构造函数。
enum pageData: Int {
case page1
case page2
case page3
static let pageGroup = [page1, page2, page3]
}
class extClass
{
func initPage(page: pageData, caption: String = "") -> myCustomType {
let text = caption.isEmpty ? getCaptionFunc(page) : caption
return myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
}
func getCaptionFunc(page: pageData) -> String {
switch page {
case .page1:
return "Page 1 Caption"
case .page2:
return "Page 2 Caption"
...
}
}
答案 2 :(得分:1)
问:安全吗?
尽管此代码在大多数情况下都可以正常工作,但绝对有机会进行一些改进。
如果这是一次代码审查,我会说使用隐式展开的myCustomType!
是一个危险的选择。您的函数需要返回一个myCustomType
,因此在每种情况下都应该这样做,并且隐式展开的变量的弊大于利。
同样,我认为这里不需要default
情况。让swift进行详尽的检查,以便您知道何时忘记执行案例。使用default
会破坏这一点。使用您编写的内容,调用pageData.page3.initPage()
将使程序崩溃,因为没有.page3
的情况,因此隐式解包的mctData
将为nil。
如果您绝对需要“关闭”编译器,则可以提供fatalError()
作为尚未实际实现的任何情况的实现。在我的书中那将是更好的选择。
关于静态功能:虽然这样做没有技术问题,但这不是我的首选解决方案。很难确定地说,因为我不知道该代码的作用,但是我可能会从pageData
类内部的实现作为计算属性开始,例如:
var defaultCaption: String {
switch self {
case .page1: // something, something "page1"
// etc. for the rest of the cases
}
}
最后,所有类名和常量名都没有标题区分大小写(例如PageData,
MyCustomType`),这使您在此处提供的代码非常不寻常,并且较难阅读。如果您还没有的话,建议您浏览一下API design guidelines语言。遵循社区标准将使您的代码对于不熟悉它的人更容易遵循。包括Stack Overflow上的人员:)