2014-06-05 18 views
22

Tôi đang cố gắng để ghi lại một enum:Logging một enum Swift sử dụng NSLog

enum CKAccountStatus : Int { 
    case CouldNotDetermine 
    case Available 
    case Restricted 
    case NoAccount 
} 

NSLog("%i", CKAccountStatus.Available) 

Trình biên dịch phàn nàn:

Type 'CKAccountStatus' does not conform to protocol 'CVarArg' 

Tại sao? Tôi đã cố gắng để cast giá trị:

NSLog("%i", CKAccountStatus.Available as Int) 

Nhưng điều đó không bay hoặc:

Cannot convert the expression's type '()' to type 'String' 
+0

bạn đã thử 'println' chưa? – Firo

+1

Tôi đã làm, nó in '(Enum Value)'. Đúng, nhưng không phải là rất hữu ích :) – zoul

Trả lời

28

Lấy số nguyên tố của enum Int giá trị: CKAccountStatus.Available.rawValue.

Enums không phải là số nguyên đúng trong Swift, nhưng nếu chúng được khai báo với kiểu cơ bản, bạn có thể lấy nó bằng rawValue - bất kể loại cơ bản đó là gì. (enum Foo: String sẽ cung cấp cho bạn chuỗi cho rawValue, vv) Nếu một enum không có một loại cơ bản, rawValue không có gì để cung cấp cho bạn. Trong các API được nhập từ ObjC, mọi enum được xác định với NS_ENUM có một loại số nguyên cơ bản (thường là Int).

Nếu bạn muốn in bất kỳ enum nào mang tính mô tả hơn, bạn có thể xem xét tạo một tiện ích mở rộng trên loại enum thông qua giao thức Printable.

+1

Tôi đã tìm thấy đơn giản 'Int' enums,' .hashValue' cũng sẽ cung cấp cho bạn quyền truy cập vào giá trị 'Int'. – tfrank377

+2

Sử dụng 'hashValue' sẽ bị lạm dụng hợp đồng API. Một kiểu 'Hashable' yêu cầu' hashValue' giống hệt với các giá trị "bằng nhau" và duy nhất khác, nhưng không đảm bảo khác ... ngay cả khi nó trùng lặp giống như 'rawValue' cho kiểu' int' enum, bạn không Không biết điều đó sẽ không thay đổi trong tương lai. Tốt nhất nên chọn API được ghi lại để làm những gì bạn muốn trên một cái xảy ra để làm những gì bạn muốn. – rickster

0

tôi thấy, sự đếm không phải là số trong Swift:

Không giống như C và Mục tiêu -C, các thành viên liệt kê Swift không được gán giá trị số nguyên mặc định là khi chúng được tạo. Trong ví dụ CompassPoints ở trên, Bắc, Nam, Đông và Tây không hoàn toàn bằng 0, 1, 2 và 3. Thay vào đó, các thành viên liệt kê khác nhau là các giá trị chính thức theo cách riêng của chúng, được xác định rõ ràng loại CompassPoint.

Có cách nào để dễ dàng ghi lại giá trị không? À, có:

NSLog("%i", CKAccountStatus.Available.toRaw()) 
1

Từ các tài liệu Swift:

Nếu bạn đã quen thuộc với C, bạn sẽ biết rằng C enumerations gán tên liên quan đến một tập hợp các giá trị số nguyên. Các số đếm trong Swift linh hoạt hơn nhiều và không phải cung cấp giá trị cho từng thành viên của liệt kê. Nếu một giá trị (được gọi là giá trị “thô”) được cung cấp cho mỗi thành viên điều tra, giá trị có thể là một chuỗi, một ký tự hoặc một giá trị của bất kỳ số nguyên hoặc loại dấu phẩy động nào.

Vì vậy, bạn không thể thử truyền đến và Int. Theo như vấn đề đầu tiên của bạn có vẻ như là NSLog() đang tìm kiếm một tham số của kiểu C-biến, mà không áp dụng cho Swift enums.

0

Bạn có thể sử dụng chức năng toRaw() để có được Int-Giá trị của enum như sau:

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" 
+0

Cách in "Sẵn có"? – CZ54

7

Một enum là một cách hiệu quả không rõ ràng. Nó có thể có giá trị thô, mà bạn có thể nhận được; nhưng nhiều enums thì không.(Bạn không phải khai báo enum là có một kiểu, và nếu bạn không, không có giá trị thô.) Những gì tôi sẽ làm là cung cấp cho enum một phương thức description và gọi nó một cách rõ ràng.

Cách duy nhất để phân biệt giá trị hiện tại của enum là thông qua lệnh chuyển đổi, vì vậy phương pháp description của bạn sẽ xử lý từng trường hợp và mỗi trường hợp của câu lệnh chuyển sẽ trả về một giá trị mô tả khác.

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 
5

Đây là cách tiếp cận của tôi:

enum UserMode : String 
{ 
    case Hold = "Hold"; 
    case Selecting = "Selecting"; 
    case Dragging = "Dragging"; 
} 

Sau đó, bất cứ khi nào tôi cần in giá trị liệu:

//Assuming I have this declared and set somewhere 
var currentMode: UserMode = .Selecting; 

Làm

NSLog("CurrentMode \(_currMode.rawValue)"); 

Sẽ in:

Chọn mã hiện tại