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

Ale*_*aro 0 struct swift

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

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?
}
Run Code Online (Sandbox Code Playgroud)

我想像这样访问变量pixel["red"],而不是pixel.red

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

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

Jos*_*ell 5

我认为这样的基于字符串的访问不是很好的Swift风格。vadian显示了如何做到的,但是要像这样动态获取和设置成员,最好使用内置的keypath功能

let redChannel = pixel[keyPath: \.red]
pixel[keyPath: \.green] = 0xB5
Run Code Online (Sandbox Code Playgroud)

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

enum Component
{
    case red
    case green
    case blue
    case alpha
}
Run Code Online (Sandbox Code Playgroud)

然后适应subscript该vadian证明接受的功能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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
var pxl = Pixel(value: 0xFEEDFACE, red: 0xFE, green: 0xED, blue: 0xFA, alpha: 0xCE)
let redChannel = pxl[.red]
print(redChannel)
pxl[.green] = 0xB5
print(pxl)
Run Code Online (Sandbox Code Playgroud)