2015-08-30 15 views
7

Tôi muốn thay thế các hằng số chuỗi toàn cục bằng một enum lồng nhau cho các khóa mà tôi đang sử dụng để truy cập các cột trong cơ sở dữ liệu.Giá trị chuỗi truy cập trong enum mà không sử dụng rawValue

Cấu trúc như sau:

enum DatabaseKeys { 

    enum User: String { 
     case Table = "User" 
     case Username = "username" 
     ... 
    } 

    ... 

} 

Mỗi bảng trong cơ sở dữ liệu là một enum bên trong, với tên của bảng là tiêu đề của enum. Trường hợp đầu tiên trong mỗi enum sẽ là tên của bảng, và các trường hợp sau là các cột trong bảng của nó.

Để sử dụng, nó khá đơn giản:

myUser[DatabaseKeys.User.Username.rawValue] = "Johnny" 

Nhưng tôi sẽ sử dụng những enums rất nhiều. Phải nối thêm .rawValue vào mọi trường hợp sẽ là một nỗi đau và không thể đọc được như tôi muốn. Làm thế nào tôi có thể truy cập vào giá trị chuỗi mà không cần phải sử dụng rawValue? Nó sẽ thật tuyệt nếu tôi có thể làm điều này:

myUser[DatabaseKeys.User.Username] = "Johnny" 

Lưu ý rằng tôi đang sử dụng Swift 2. Nếu có một cách tốt hơn để thực hiện điều này tôi muốn nghe nó!

+0

Những loại đối tượng là '' 'myUser'''? Một từ điển hoặc đối tượng của riêng bạn với một subscript? –

+0

@AndyIbanez Nó có thể là một từ điển đơn giản, hoặc một PFUser trong trường hợp của tôi khi tôi đang sử dụng Parse – Joey

Trả lời

14

Mặc dù tôi không tìm cách thực hiện việc này bằng cú pháp mong muốn với enums, điều này có thể sử dụng cấu trúc.

struct DatabaseKeys { 

    struct User { 
     static let identifier = "User" 
     static let Username = "username" 
    } 

} 

Cách sử dụng:

myUser[DatabaseKeys.User.Username] = "Johnny" 

Apple sử dụng cấu trúc như thế này cho kịch bản và loại hàng định danh trong các mẫu WatchKit.

+0

Điều tốt để biết rằng ~ thx buddy – Jerome

6

Bạn có thể sử dụng giao thức CustomStringConvertible cho việc này.

Từ tài liệu,

String (chẳng hạn) sẽ làm việc cho một thể hiện của bất kỳ loại, trở về mô tả của nó nếu trường hợp xảy ra là CustomStringConvertible. Sử dụng CustomStringConvertible làm ràng buộc chung, hoặc truy cập trực tiếp vào mô tả của loại phù hợp của loại phù hợp, do đó không khuyến khích.

Vì vậy, nếu bạn tuân thủ giao thức này và trả về rawValue thông qua phương pháp mô tả, bạn sẽ có thể sử dụng String (Table.User) để lấy giá trị.

enum User: String, CustomStringConvertible { 

    case Table = "User" 
    case Username = "username" 

    var description: String { 
     return self.rawValue 
    } 
} 

var myUser = [String: String]() 
myUser[String(DatabaseKeys.User.Username)] = "Johnny" 

print(myUser) // ["username": "Johnny"] 
+1

Cảm ơn, điều đó thật thú vị. Mặc dù phải sử dụng 'String' để khởi tạo một chuỗi chỉ là không hiệu quả. : P Tôi thực sự muốn sử dụng 'rawValue' hơn là gói nó trong' String() '. – Joey

0

Nếu bạn có thể sử dụng User chìa khóa như từ điển thay vì String (UserHashable theo mặc định) nó sẽ là một giải pháp.

Nếu không, bạn nên sử dụng máy của bạn với cấu trúc lồng nhau và biến tĩnh/hằng số.

0

Bạn có thể làm điều này với lớp tùy chỉnh:

enum Names: String { 
    case something, thing 
} 

class CustomData { 
    subscript(key: Names) -> Any? { 
     get { 
      return self.customData[key.rawValue] 
     } 

     set(newValue) { 
      self.customData[key.rawValue] = newValue 
     } 
    } 

    private var customData = [String: Any]() 
} 

... 

let cData = CustomData() 
cData[Names.thing] = 56 

Edit:
Tôi tìm thấy một giải pháp khác, đó là làm việc với Swift 3:

enum CustomKey: String { 
    case one, two, three 
} 

extension Dictionary where Key: ExpressibleByStringLiteral { 
    subscript(key: CustomKey) -> Value? { 
     get { 
      return self[key.rawValue as! Key] 
     } 
     set { 
      self[key.rawValue as! Key] = newValue 
     } 
    } 
} 

var dict: [String: Any] = [:] 
dict[CustomKey.one] = 1 
dict["two"] = true 
dict[.three] = 3 
print(dict["one"]!) 
print(dict[CustomKey.two]!) 
print(dict[.three]!) 
+0

Có cách nào để thực hiện điều này cho tất cả các enums kế thừa từ một lớp cơ sở? –

+0

Điều này chỉ dành cho việc sử dụng enum làm khóa từ điển? –

Các vấn đề liên quan