我有一个结构,我想知道我是否可以使用括号语法访问变量。这是我的结构:
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中这样做?
答案 0 :(得分:5)
我不认为像这样的基于字符串的访问是很好的Swift风格。 vadian shows如何做到这一点,但要像这样动态获取和设置成员,最好使用the built-in keypath functionality:
let redChannel = pixel[keyPath: \.red]
pixel[keyPath: \.green] = 0xB5
另一个选项(在Swift 4之前更相关)是使用枚举来定义键:
enum Component
{
case red
case green
case blue
case alpha
}
然后调整vadian演示接受subscript
而不是Pixel.Component
的{{1}}函数。
这具有明显的优势,因为您无法再传递无效密钥。
根据您的定义:
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
}
}
}
}
答案 1 :(得分:3)
您所描述的不是Swift功能,除非您使用下标(如vadian所解释的)。如果您想要自动提供下载的内容,请使用字典。否则,如果你真的想要真正的内省,使用Cocoa - 使用从NSObject派生的类而不是结构,并使用键值编码。
答案 2 :(得分:1)
只是为了好玩并表明它是可能的,但它很难看
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")
}
}
}
}
答案 3 :(得分:0)
如果OP正在寻找更清洁的替代方案,那么有一个将KVC扩展到本机Swift结构的pod: