[英]In Swift, can one use a string to access a struct property?
我有一個結構,我想知道是否可以使用括號語法訪問變量。 這是我的結構:
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中有什么方法可以做到這一點?
我認為這樣的基於字符串的訪問不是很好的Swift風格。 vadian顯示了如何做到的,但是要像這樣動態獲取和設置成員,最好使用內置的keypath功能 :
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
而不是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
}
}
}
}
var pxl = Pixel(value: 0xFEEDFACE, red: 0xFE, green: 0xED, blue: 0xFA, alpha: 0xCE)
let redChannel = pxl[.red]
print(redChannel)
pxl[.green] = 0xB5
print(pxl)
除非您使用下標(如vadian所述),否則您所描述的不是Swift功能。 如果您需要自動提供下標的內容,請使用字典。 否則,如果您確實想要真正的自省,請使用Cocoa-使用從NSObject派生的類而不是結構,並使用鍵值編碼。
只是為了娛樂並表明它是可能的,但是它很丑
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")
}
}
}
}
如果OP正在尋找更清潔的替代方案,則可以使用一個吊艙將KVC擴展到本機Swift結構:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.