Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Swift中,可以使用字符串访问结构属性吗?_Swift_Struct - Fatal编程技术网

在Swift中,可以使用字符串访问结构属性吗?

在Swift中,可以使用字符串访问结构属性吗?,swift,struct,Swift,Struct,我有一个结构,我想知道是否可以使用括号语法访问变量。这是我的结构: import UIKit public struct Pixel { public var value: UInt32 public var red: UInt8 public var green: UInt8 public var blue: UInt8 public var alpha: UInt8 } public struct RGBAImage { public va

我有一个结构,我想知道是否可以使用括号语法访问变量。这是我的结构:

import UIKit

public struct Pixel {
    public var value: UInt32
    public var red: UInt8
    public var green: UInt8
    public var blue: UInt8
    public var alpha: UInt8
}

public struct RGBAImage {
    public var pixels: [ImageProcessor_Sources.Pixel]
    public var width: Int
    public var height: Int
    public init?(image: UIImage)
    public func toUIImage() -> UIImage?
}
我想访问像这样的变量
pixel[“red”]
,而不是
pixel.red

var image = RGBAImage(image: image!)!
var pixel = image.pixels[index]
pixel["red"] = 255 // as opposed to pixel.red

在Swift中有什么方法可以做到这一点吗?

只是为了好玩并表明这是可能的,但这很难看

public struct Pixel {
  public var value: UInt32
  public var red: UInt8
  public var green: UInt8
  public var blue: UInt8
  public var alpha: UInt8

  subscript(key: String) -> UInt8 {
    get {
      switch key {
      case "red": return self.red
      case "green": return self.green
      case "blue": return self.blue
      case "alpha": return self.alpha
      default: fatalError("Invalid key")
      }
    }
    set {
      switch key {
      case "red": self.red = newValue
      case "green": self.green = newValue
      case "blue": self.blue = newValue
      case "alpha": self.alpha = newValue
      default: fatalError("Invalid key")
      }
    }
  }
}

只是为了好玩,为了证明这是可能的,但这很难看

public struct Pixel {
  public var value: UInt32
  public var red: UInt8
  public var green: UInt8
  public var blue: UInt8
  public var alpha: UInt8

  subscript(key: String) -> UInt8 {
    get {
      switch key {
      case "red": return self.red
      case "green": return self.green
      case "blue": return self.blue
      case "alpha": return self.alpha
      default: fatalError("Invalid key")
      }
    }
    set {
      switch key {
      case "red": self.red = newValue
      case "green": self.green = newValue
      case "blue": self.blue = newValue
      case "alpha": self.alpha = newValue
      default: fatalError("Invalid key")
      }
    }
  }
}

您所描述的不是Swift特性,除非您使用订阅(正如瓦迪安所解释的)。如果你想要自动订阅的东西,可以使用字典。否则,如果您真的想要真正的内省,请使用Cocoa—使用从NSObject派生的类而不是结构,并使用键值编码。

您所描述的不是Swift特性,除非您使用订阅(正如vadian所解释的)。如果你想要自动订阅的东西,可以使用字典。否则,如果您真的想要真正的内省,请使用Cocoa—使用从NSObject派生的类而不是结构,并使用键值编码。

我认为这样基于字符串的访问不是好的Swift风格。如何实现,但要像这样动态获取和设置成员,最好使用:

另一种选择(在Swift 4之前更相关)是使用枚举定义键:

enum Component
{
    case red
    case green
    case blue
    case alpha
}
然后调整vadian演示的
subscript
函数,以接受
Pixel.Component
而不是
String

这有一个显著的优点,即您不能再传递无效的密钥

根据您的定义:

public extension Pixel
{
    public enum Component
    {
        case red, blue, green, alpha
    }

    public subscript(key: Component) -> UInt8
    {
        get
        {
            switch key {
                case .red: return self.red
                case .green: return self.green
                case .blue: return self.blue
                case .alpha: return self.alpha
            }
        }
        set
        {
            switch key {
                case .red: self.red = newValue
                case .green: self.green = newValue
                case .blue: self.blue = newValue
                case .alpha: self.alpha = newValue
            }
        }
    }
}


我不认为像这样基于字符串的访问是好的Swift风格。如何实现,但要像这样动态获取和设置成员,最好使用:

另一种选择(在Swift 4之前更相关)是使用枚举定义键:

enum Component
{
    case red
    case green
    case blue
    case alpha
}
然后调整vadian演示的
subscript
函数,以接受
Pixel.Component
而不是
String

这有一个显著的优点,即您不能再传递无效的密钥

根据您的定义:

public extension Pixel
{
    public enum Component
    {
        case red, blue, green, alpha
    }

    public subscript(key: Component) -> UInt8
    {
        get
        {
            switch key {
                case .red: return self.red
                case .green: return self.green
                case .blue: return self.blue
                case .alpha: return self.alpha
            }
        }
        set
        {
            switch key {
                case .red: self.red = newValue
                case .green: self.green = newValue
                case .blue: self.blue = newValue
                case .alpha: self.alpha = newValue
            }
        }
    }
}


如果OP正在寻找更干净的替代方案,那么有一个pod可以将KVC扩展到本机Swift结构:


如果OP正在寻找更干净的替代方案,那么有一个pod可以将KVC扩展到本机Swift结构:


不可以(除非为组件创建字典或自定义订阅逻辑)。字符串订阅的好处是什么?文字字符串总是容易出错。如果出现
pixel[“aosiubd”]
,该怎么办?好吧,我正在努力保持干燥。我同意事情会更容易出错,但我希望能够将字符串传递到函数中,并将其用作查找,类似于python字典键。我现在必须为红色、绿色和蓝色通道编写这组代码:
pixel.RED=UInt8(max(0,min(255,rgbArray[0]+diff*intensity))
“我希望能够将字符串传递到函数中并将其用作查找,类似于python字典键”,然后使用字典,而不是结构。谢谢@matt will doNo你不能这样做(除非您为组件或自定义订阅逻辑创建字典)。订阅字符串有什么好处?文本字符串总是容易出错。如果出现
pixel[“aosiubd”]
?好吧,我正在努力让事情保持干爽。我同意事情会更容易出错,但我希望能够将字符串传递到函数中并将其用作查找,类似于python字典键。我现在必须为红色、绿色和蓝色通道编写这组代码:
pixel.RED=UInt8(max(0,min)(255,rgbArray[0]+diff*intensity))
“我希望能够将字符串传递到函数中,并将其用作查找,类似于python字典键。”然后使用字典,而不是结构。谢谢@matt will doThanks@Josh,如果你能演示添加下标以接受像素组件而不是字符串,我会将其标记为正确答案。这是对vadian代码的直接转换;我添加了它以确保完整性。谢谢@Josh,如果你能演示添加下标以接受像素组件而不是字符串,我将把它标记为正确答案。这是对瓦迪安代码的直接转换;为了完整性,我添加了它。