[英]Get enumeration name when using associated values
我的枚举定义如下
enum Fruit {
case Apple(associatedValue: String)
case Orange(associatedValue: String)
}
我有一个函数,它接受类型为Fruit的参数
func printNameOnly(fruit: Fruit) {
}
在这个函数中,我想把枚举的情况作为一个字符串,即我想得到字符串“Apple”或“Orange”,而不考虑相关的值。 Swift可以实现吗?
我显然可以编写一个函数,它接受水果枚举并使用case语句返回一个字符串,但我试图找到一种方法来避免这种情况,因为我想要的字符串是enum case name本身。
试试这个(Swift 3.1)。 涵盖相关或常规案例。
enum Fruit {
case banana
case apple(String)
case orange(String)
var label:String {
let mirror = Mirror(reflecting: self)
if let label = mirror.children.first?.label {
return label
} else {
return String(describing:self)
}
}
}
print(Fruit.banana.label) // "banana"
print(Fruit.apple("yum").label) // "apple"
所以你想要一个带有RawValue 和相关值的Swift枚举。
我能想到的最好的解决方案是为你的枚举添加一个计算属性(类似于你在自己的问题中建议的那样)。
enum Fruit {
case Apple(name:String)
case Orange(name:String)
var fruitDesc: String {
switch self {
case .Apple: return "Apple"
case .Orange: return "Orange"
}
}
}
let fruit = Fruit.Apple(name: "McIntosh")
print(fruit.fruitDesc) // Apple
当枚举具有关联值时,打印它们将列出所有值以及枚举名称。 例如:
let anApple = Fruit.Apple("myApple")
print(anApple)
这将产生:
Apple("myApple")
因此,要获得“Apple”,将部分提取到第一个“(”。
如果你想获得枚举案例标签以进行调试,那么来自Swift运行时的这个整洁的私有反射函数可能会派上用场:
/// Returns the case label for the given enumeration value.
public func getEnumCaseName<T>(_ value: T) -> String? {
return __getEnumCaseName(value).flatMap { String(validatingUTF8: $0) }
}
/// A private Swift function from the compiler which returns the case
/// label of the given enumeration value, represented as a C string.
@_silgen_name("swift_EnumCaseName")
fileprivate func __getEnumCaseName<T>(_ value: T) -> UnsafePointer<CChar>?
我只用Swift 4测试了这种方法。 如上所述,我不建议将其用于生产代码,而是仅用于调试实用程序,因为它是私有/未记录的API,并且可能在将来的Swift版本中中断。
是的,反射API可以提供帮助。 这个可以在调试和生产中使用。
enum Fruit {
case apple(associatedValue: String)
case orange(associatedValue: String)
}
func fruitNameOnly(fruit: Fruit) -> String {
return Mirror(reflecting: fruit).children.first!.label!
}
let greenApple = Fruit.apple(associatedValue: "Green")
print(fruitNameOnly(fruit: greenApple)) // apple
扩展版,利用相关 和原始值的:
enum Fruit: RawRepresentable {
case apple(associatedValue: String)
case orange(associatedValue: String)
typealias RawValue = String
var rawValue: String {
//return Mirror(reflecting: self).children.first!.label!
// we rather use a regular switch this time which allows for custom values
switch self {
case .apple: return "apple"
case .orange(let av): return "orange " + av // Edge case, careful!
// Normally rawValues should form one to one relationship.
// RawRepresentable protocol indicates, that you can "switch back and forth between a custom type and an associated RawValue type without losing the value of the original RawRepresentable type" (developer.apple.com/documentation/swift/rawrepresentable)
}
}
init?(rawValue: String) {
switch rawValue {
case "apple":
self = .apple(associatedValue: "")
case "orange":
self = .orange(associatedValue: "")
default:
return nil
}
}
}
func fruitNameOnly(fruit: Fruit) -> String {
return Mirror(reflecting: fruit).children.first!.label!
}
let greenApple = Fruit.apple(associatedValue: "green")
print(fruitNameOnly(fruit: greenApple)) // apple
if let yellowOrange = Fruit.init(rawValue: "orange") {
print(yellowOrange) // orange(associatedValue: "")
}
print(greenApple.rawValue) //apple
let redOrange = Fruit.orange(associatedValue: "red")
print(redOrange.rawValue) //orange red
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.