【问题标题】:Swift - Associated value or extension for an EnumSwift - 枚举的关联值或扩展
【发布时间】:2015-04-28 09:48:42
【问题描述】:

关于快速枚举的一般问题。

我想创建一个“图标”枚举并将一个值“关联”到枚举案例

enum Icon {
  case plane
  case arrow
  case logo
  case flag
}

我想创建一个与枚举值关联的图像。 以及与枚举值相关的颜色

例如,如果可以执行以下操作:

extension Icon.plane {
  var image = {
    get {
       return UIImage("plane.png")
    }
  }
  var color = {
    get {
       return UIColor.greenColor()
    }
  }
}


var image = Icon.arrow.image // the image associated to the enum
var color = Icon.arrow.color // the color associated to the enum

这种事情可能吗?

【问题讨论】:

    标签: swift enums associated-object associated-types computed-values


    【解决方案1】:

    很遗憾,您不能基于枚举案例定义静态属性,但您可以使用计算属性和switch 为每个案例返回值:

    enum Icon {
        case plane
        case arrow
        case logo
        case flag
    
        var image: UIImage {
            switch self {
                case .plane: return UIImage(named: "plane.png")!
                case .arrow: return UIImage(named: "arrow.png")!
                case .logo: return UIImage(named: "logo.png")!
                case .flag: return UIImage(named: "flag.png")!
            }
        }
    
        var color: UIColor {
            switch self {
            case .plane: return UIColor.greenColor()
            case .arrow: return UIColor.greenColor()
            case .logo: return UIColor.greenColor()
            case .flag: return UIColor.greenColor()
            }
        }
    }
    
    // usage
    Icon.plane.color
    

    【讨论】:

      【解决方案2】:

      将带有关联值的枚举与 switch 语句结合使用,您可以非常灵活。第一个例子:

      enum Icon {
          case plane(img:UIImage, col:UIColor)
          case arrow(img:UIImage, col:UIColor)
          case logo(img:UIImage, col:UIColor)
          case flag(img:UIImage, col:UIColor)
      
          var values:(img:UIImage,col:UIColor) {
              switch self {
              case let .plane(image, color):
                  return (image,color)
              case let .arrow(image, color):
                  return (image,color)
              case let .logo(image, color):
                  return (image,color)
              case let .flag(image, color):
                  return (image,color)
              }
          }
      }
      
      
      
      var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
      
      a.values.col
      a.values.img
      

      还有第二个例子:

      enum Icon {
          case plane(img:UIImage, col:UIColor)
          case arrow(img:UIImage, col:UIColor)
          case logo(img:UIImage, col:UIColor)
          case flag(img:UIImage, col:UIColor)
      
          var img:UIImage {
              switch self {
              case let .plane(image, color):
                  return image
              case let .arrow(image, color):
                  return image
              case let .logo(image, color):
                  return image
              case let .flag(image, color):
                  return image
              }
          }
      
          var col:UIColor {
              switch self {
              case let .plane(image, color):
                  return color
              case let .arrow(image, color):
                  return color
              case let .logo(image, color):
                  return color
              case let .flag(image, color):
                  return color
              }
          }
      }
      
      
      
      var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
      
      a.col
      a.img
      

      无需扩展。如果你真的想要静态值,你可以这样做:

      struct MyIcon {
          static let plane = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
          static let arrow = Icon.arrow(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
          static let logo = Icon.logo(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
          static let flag = Icon.flag(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
      }
      
      MyIcon.arrow.col
      

      这可能比将固定文字值放在 switch 语句中更整洁。

      【讨论】:

        【解决方案3】:

        更短更安全的代码:

        import UIKit
        
        enum Icon: String {
        
            case plane, arrow, logo, flag
        
            var image: UIImage {
        
                // If the image is not available, provide a default value so we dont force optional unwrapping
                return UIImage(named: "\(self.rawValue).png") ?? UIImage()
            }
        
            var color: UIColor {
                switch self {
                case .plane: return UIColor.green
                case .arrow: return UIColor.green
                case .logo: return UIColor.green
                case .flag: return UIColor.green
                }
            }
        }
        
        // Usage
        Icon.plane.color
        Icon.arrow.image
        

        【讨论】:

          【解决方案4】:

          更简洁易读

          enum Icon {
              case plane
              case arrow
              case logo
              case flag
          
              var image: UIImage {
                  return value.image
              }
          
              var color: UIColor {
                  return value.color
              }
          
              private var value: (image: UIImage, color: UIColor) {
                  switch self {
                  case .plane: return (UIImage(named: "plane.png")!, UIColor.green)
                  case .arrow: return (UIImage(named: "arrow.png")!, UIColor.green)
                  case .logo: return (UIImage(named: "logo.png")!, UIColor.green)
                  case .flag: return (UIImage(named: "flag.png")!, UIColor.green)
                  }
              }
          }
          
          // Use
          Icon.plane.image
          Icon.plane.color
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-09
            相关资源
            最近更新 更多