【问题标题】:Comparing enums with arguments比较枚举和参数
【发布时间】:2018-01-09 12:27:28
【问题描述】:

这是我拥有的一些枚举:

enum SlideTemplate : Equatable {
    case centered(content: SlideContent)
    case horizontalSplit(leftContent: SlideContent, rightContent: SlideContent)
    case empty

    static func == (lhs: SlideTemplate, rhs: SlideTemplate) -> Bool {
        // not sure what to do here
    }
}

enum SlideContent {
    case text(content: String)
    case image(content: UIImage)
}

struct Slide {
    let template: SlideTemplate
}

现在我想检查一下幻灯片的模板类型。

func getSlideTemplate(slide: Slide) {
    if slide.template == SlideTemplate.centered {
        print("centered")
    } else if slide.template == SlideTemplate.horizontalSplit {
        print("horizontalSplit")
    } else {
        print("empty")
    }
}

上述功能显然不起作用。它指出:

“二元运算符'=='不能应用于'SlideTemplate'和'(SlideContent, SlideContent) -> SlideTemplate'类型的操作数”

我不确定如何解决这个问题。我查找了其他比较枚举的案例,但我无法将这些案例应用于这种情况。

【问题讨论】:

    标签: ios swift enums


    【解决方案1】:

    主要思想是在需要时比较相关值和raw 值。所以,你==func 可以是这样的:

    static func == (lhs: SlideTemplate, rhs: SlideTemplate) -> Bool {
        switch (lhs, rhs) {
        case let (.centered(lvalue), .centered(rvalue)):
            return lvalue == rvalue
        case let (.horizontalSplit(lleft, lright), .horizontalSplit(rleft, rright)):
            return lleft == rleft && lright == rright
        case (.empty, .empty):
            return true
        default:
            return false
        }
    }
    

    例如,如果您不需要比较.centeredraw 值,则可以只检查相关值:

    ...
    case (.centered, .centered):
        return true
    ...
    

    正如@user28434 提到的,您应该使SlideContent 也符合Equatable 协议。

    static func ==(lhs: SlideContent, rhs: SlideContent) -> Bool {
        switch (lhs, rhs) {
        case let (.text(lcontent), .text(rcontent)):
            return lcontent == rcontent
        case let (.image(lcontent), .image(rcontent)):
            return lcontent == rcontent
        default:
            return false
        }
    }
    

    现在您可以通过== full-typed-values 进行比较,例如:

    if slide.template == SlideTemplate.centered(content: SlideContent.text(content: "SomeContent")) {
        print("centered for SomeContent")
    }
    

    要快速比较相关值,您可以使用if case 构造:

    if case .centered = slide.template {
        print("centered")
    }
    

    结论

    • 如果你想知道“什么类型的SlideTemplate 包含这个属性” - 使用if case .centered = slide.template { ... } 方式而不实现Equatable 协议。
    • 如果您想完全比较 SlideTemplate 属性 - 实现 Equatable 协议并将它们与 == 进行比较。

    【讨论】:

    • 注意:SlideContent 也应该是 Equatable 以进行完整比较(第一个代码段)。
    • @pacification 我实现了这个。但是,我原来问题中的函数仍然给我同样的错误。
    【解决方案2】:

    如果您只需要检查getSlideTemplate 中的枚举值,您实际上根本不需要==

    只需使用if case:

    func getSlideTemplate(slide: Slide) {
        if case SlideTemplate.centered = slide.template {
            print("centered")
        } else if case SlideTemplate.horizontalSplit = slide.template {
            print("horizontalSplit")
        } else {
            print("empty")
        }
    }
    

    或者,更好的是switch

    func getSlideTemplate(slide: Slide) {
        switch slide.template {
        case .centered:
            print("centered")
        case .horizontalSplit:
            print("horizontalSplit")
        case .empty:
            print("empty")
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您也比较内容,这可能对您有用

      enum SlideTemplate : Equatable {
          case centered(content: SlideContent)
          case horizontalSplit(leftContent: SlideContent, rightContent: SlideContent)
          case empty
      
          static func == (lhs: SlideTemplate, rhs: SlideTemplate) -> Bool {
              // not sure what to do here
      
              switch  lhs {
              case .centered(let content):
                  switch rhs {
                  case .centered(content: let rhsContent):
                      return content == rhsContent
                  default:
                      return false
                  }
              case .horizontalSplit(let leftContent, let rightContent):
                  switch rhs {
                  case .horizontalSplit(let rhsLeftContent, let rhsRightContent):
                      return leftContent == rhsLeftContent && rightContent == rhsRightContent
                  default:
                      return false
                  }
              case .empty:
                  switch rhs {
                  case .empty:
                      return true
                  default:
                      return false
                  }
              }
          }
      }
      
      enum SlideContent: Equatable {
      
          case text(content: String)
          case image(content: UIImage)
      
          static func ==(lhs: SlideContent, rhs: SlideContent) -> Bool {
              switch lhs {
              case .text(let content):
                  switch  rhs {
                  case .text(let rhsContent):
                      return content == rhsContent
                  default:
                      return false
                  }
              case .image(let content):
                  switch rhs {
                  case .image(let rhsContent):
                      return content == rhsContent
                  default:
                      return false
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-05-04
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多