使用 NSLog 记录 Swift 枚举
Posted
技术标签:
【中文标题】使用 NSLog 记录 Swift 枚举【英文标题】:Logging a Swift enum using NSLog 【发布时间】:2014-06-05 13:36:50 【问题描述】:我正在尝试记录一个枚举:
enum CKAccountStatus : Int
case CouldNotDetermine
case Available
case Restricted
case NoAccount
NSLog("%i", CKAccountStatus.Available)
编译器抱怨:
Type 'CKAccountStatus' does not conform to protocol 'CVarArg'
为什么?我试图转换值:
NSLog("%i", CKAccountStatus.Available as Int)
但这也不行:
Cannot convert the expression's type '()' to type 'String'
【问题讨论】:
你试过println
吗?
我做了,它打印出(Enum Value)
。正确,但不是很有帮助:)
【参考方案1】:
获取枚举的底层Int
值:CKAccountStatus.Available.rawValue
。
枚举在 Swift 中并不是严格的整数,但如果它们是用底层类型声明的,你可以用 rawValue
来获得它——不管底层类型是什么。 (enum Foo: String
将为您提供 rawValue
等的字符串。)如果枚举没有基础类型,rawValue
将无能为力。在从 ObjC 导入的 API 中,使用 NS_ENUM
定义的任何枚举都具有底层整数类型(通常为 Int
)。
如果您想打印更具描述性的枚举,您可以考虑对采用Printable
协议的枚举类型进行扩展。
【讨论】:
我发现对于简单的Int
枚举,.hashValue
还可以让您访问Int
值。
使用 hashValue
会滥用 API 合约。 Hashable
类型要求 hashValue
对于“相等”值是相同的,否则是唯一的,但不做其他保证......即使它巧合地返回与 rawValue
相同的 Int
枚举类型,你不要不知道将来不会改变。最好选择记录在案的 API 来做你想做的事,而不是碰巧做你想做的事。【参考方案2】:
枚举实际上是不透明的。它可能有原始值,你可以得到;但许多枚举没有。 (您不必将枚举声明为具有类型,如果不声明,则没有原始值。)我要做的是给枚举一个 description
方法并显式调用它。
区分枚举当前值的唯一方法是通过 switch 语句,因此您的description
方法将处理每种情况,并且 switch 语句的每种情况都会返回不同的描述性值。
enum Suit
case Hearts, Diamonds, Spades, Clubs
func description () -> String
switch self
case Hearts:
return "hearts"
case Diamonds:
return "diamonds"
case Spades:
return "spades"
case Clubs:
return "clubs"
var suit = Suit.Diamonds
println("suit \(suit.description())") // suit diamonds
【讨论】:
【参考方案3】:这是我的方法:
enum UserMode : String
case Hold = "Hold";
case Selecting = "Selecting";
case Dragging = "Dragging";
然后,每当我需要打印原始值时:
//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;
在做
NSLog("CurrentMode \(_currMode.rawValue)");
将打印:
当前模式选择
【讨论】:
【参考方案4】:来自 Swift 文档:
如果您熟悉 C,您就会知道 C 枚举将相关名称分配给一组整数值。 Swift 中的枚举更加灵活,并且不必为枚举的每个成员提供值。如果为每个枚举成员提供了一个值(称为“原始”值),则该值可以是字符串、字符或任何整数或浮点类型的值。
因此,您不能尝试将其强制转换为和 Int。至于您的第一个问题,NSLog()
似乎正在寻找 C 变量类型的参数,这不适用于 Swift 枚举。
【讨论】:
【参考方案5】:我明白了,在 Swift 中枚举不是数字:
与 C 和 Objective-C 不同,Swift 枚举成员没有分配一个 创建时的默认整数值。在指南针点 上面的例子,North、South、East 和 West 不隐式等于 0, 1、2和3。相反,不同的枚举成员是 完全成熟的价值观,具有明确定义的 CompassPoint 的类型。
那么有没有办法轻松记录该值?啊,有:
NSLog("%i", CKAccountStatus.Available.toRaw())
【讨论】:
【参考方案6】:您可以使用toRaw()
函数获取枚举的 Int-Value,如下所示:
import Foundation
enum CKAccountStatus : Int
case CouldNotDetermine
case Available
case Restricted
case NoAccount
let block = (status: Int) -> Void in
NSLog("%d", status)
let status = CKAccountStatus.Available.toRaw()
block(status) // prints "1"
【讨论】:
如何打印“可用”?【参考方案7】:对于我的错误枚举,我使用
public var localizedDescription : String return String(reflecting: self)
对于其他枚举,可以使用 CustomStringConvertible 协议
public var description : String return String(reflecting: self)
【讨论】:
以上是关于使用 NSLog 记录 Swift 枚举的主要内容,如果未能解决你的问题,请参考以下文章
是否有NSLog的Swift替代方案(@“%s”,__ PRETTY_FUNCTION__)
NSLog(@"%s", __PRETTY_FUNCTION__) 是不是有 Swift 替代方案