2014-12-30 18 views
9

Tôi muốn kết hợp hai giá trị nguyên với một thể hiện enum (tưởng tượng một enum đại diện cho các loại lỗi, tôi muốn Error.Teapot để có một loại tài sản code Int với giá trị 418, và một tài sản Chuỗi thiết lập để I'm a teapot.)Enums Swift có thể có nhiều giá trị thô không?

Note sự khác biệt giữa raw valuesassociated values ở đây — Tôi muốn tất cả Teapot trường hợp có số code của 418, tôi không muốn một giá trị được liên kết duy nhất cho mỗi phiên bản Teapot.

Có cách nào tốt hơn so với thêm thuộc tính được tính vào enum mà switch chỉnh sửa trên self để tra cứu giá trị thích hợp không?

Trả lời

8

Không, enum không thể có nhiều giá trị thô - nó phải là một giá trị duy nhất, triển khai giao thức Equatable và có thể chuyển đổi theo nghĩa đen như được mô tả trong documentation.

Tôi nghĩ cách tiếp cận tốt nhất trong trường hợp của bạn là sử dụng mã lỗi làm giá trị thô và thuộc tính được hỗ trợ bởi từ điển tĩnh được điều chế trước với mã lỗi là khóa và văn bản làm giá trị.

2

Không, bạn không thể có nhiều giá trị thô được kết hợp với enum.

Trong trường hợp của bạn, bạn có thể có giá trị thô bằng mã và có giá trị được liên kết với mô tả. Nhưng tôi nghĩ cách tiếp cận thuộc tính được tính toán là lựa chọn tốt nhất ở đây.

+0

Một giá trị gắn liền với mô tả sẽ không được chính xác cho những gì tôi muốn. Tất cả các trường hợp 'Teapot' phải có cùng một chuỗi; Tôi muốn sử dụng một giá trị String liên quan nếu tôi muốn đính kèm nói, một lưu ý về nguồn gốc của một cá thể lỗi cụ thể. –

1

Một giải pháp thay thế nếu bạn muốn có nhiều thuộc tính tĩnh cho một YourError có thể nhập danh sách thuộc tính; bạn có thể đặt đối tượng gốc thành một từ điển, với giá trị enum thô của bạn làm khóa cho mỗi đối tượng, cho phép bạn dễ dàng truy xuất dữ liệu có cấu trúc tĩnh cho đối tượng.

này có một ví dụ về nhập khẩu và sử dụng một plist: http://www.spritekitlessons.com/parsing-a-property-list-using-swift/

Đó có thể là quá mức cần thiết cho đơn giản là một mô tả lỗi, mà bạn chỉ có thể sử dụng một hàm tĩnh hardcoded với một tuyên bố chuyển đổi cho các giá trị enum của bạn, mà trả về chuỗi lỗi bạn cần. Chỉ cần đặt hàm tĩnh trong cùng một tệp .swift làm enum của bạn.

Ví dụ,

static func codeForError(error : YourErrorType) -> Int { 
    switch(error) { 
     case .Teapot: 
      return "I'm a Teapot" 
     case .Teacup: 
      return "I'm a Teacup" 
     ... 
     default: 
      return "Unknown Teaware Error" 
    } 
} 

này có lợi ích (so với các giải pháp plist) của địa phương hóa có sức chứa tốt hơn. Tuy nhiên, một .plist chỉ có thể chứa một khóa được sử dụng để lấy nội địa hóa thích hợp, thay vì một chuỗi lỗi, cho mục đích này.

0

Tôi đã tạo ra một cách để mô phỏng điều này (Không khác với những gì Marcos Crispino đề xuất về câu trả lời của mình). Xa một giải pháp hoàn hảo nhưng cho phép chúng tôi tránh những trường hợp chuyển đổi khó chịu cho mọi tài sản khác nhau mà chúng tôi muốn nhận được.

Bí quyết là sử dụng cấu trúc làm chủ sở hữu "dữ liệu/dữ liệu" và sử dụng nó làm RawValue trong chính enum.

Nó có một chút trùng lặp nhưng nó phục vụ tốt cho đến nay. Mỗi khi bạn muốn thêm một trường hợp enum mới, trình biên dịch sẽ nhắc nhở bạn điền vào trường hợp bổ sung trong getV rawue, sẽ nhắc bạn cập nhật init? để nhắc bạn tạo thuộc tính tĩnh mới trên cấu trúc.

Gist

Mã đến Gist:

enum VehicleType : RawRepresentable { 

    struct Vehicle : Equatable { 
     let name: String 
     let wheels: Int 

     static func ==(l: Vehicle, r: Vehicle) -> Bool { 
      return l.name == r.name && l.wheels == r.wheels 
     } 

     static var bike: Vehicle { 
      return Vehicle(name: "Bicycle", wheels: 2) 
     } 

     static var car: Vehicle { 
      return Vehicle(name: "Automobile", wheels: 4) 
     } 

     static var bus: Vehicle { 
      return Vehicle(name: "Autobus", wheels: 8) 
     } 
    } 

    typealias RawValue = Vehicle 

    case car 
    case bus 
    case bike 

    var rawValue: RawValue { 
     switch self { 
     case .car: 
      return Vehicle.car 
     case .bike: 
      return Vehicle.bike 
     case .bus: 
      return Vehicle.bus 
     } 
    } 

    init?(rawValue: RawValue) { 
     switch rawValue { 
     case Vehicle.bike: 
      self = .bike 
     case Vehicle.car: 
      self = .car 
     case Vehicle.bus: 
      self = .bus 
     default: return nil 
     } 
    } 
} 

VehicleType.bike.rawValue.name 
VehicleType.bike.rawValue.wheels 
VehicleType.car.rawValue.wheels 

VehicleType(rawValue: .bike)?.rawValue.name => "Bicycle" 
VehicleType(rawValue: .bike)?.rawValue.wheels => 2 
VehicleType(rawValue: .car)?.rawValue.name => "Automobile" 
VehicleType(rawValue: .car)?.rawValue.wheels => 4 
VehicleType(rawValue: .bus)?.rawValue.name => "Autobus" 
VehicleType(rawValue: .bus)?.rawValue.wheels => 8 
Các vấn đề liên quan