我有一个结构,我想知道是否可以使用括号语法访问变量。这是我的结构:
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中有什么方法可以做到这一点?
我认为这样的基于字符串的访问不是很好的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)