从ENUM函数中调用外部类函数

时间:2018-12-04 21:51:21

标签: swift enums switch-statement

我最近在 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()返回的必需数据。

问:这是一个安全/允许的设计吗?到目前为止,测试尚无定论,当枚举和开关盒太大时,应用程序将崩溃,但在较小的占用空间下可以正常工作。

谢谢您的反馈。

3 个答案:

答案 0 :(得分:1)

“安全”是什么意思?您的代码包含不正确的语法。 请勿使用强制展开的值myCustomType!

  1. 使用正确的大小写> :String的字符串值映射

  2. pageGroup

  3. 使用正确的代码语法
  4. 使用完全切换

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上的人员:)