Reputation: 16430
Is this possible to create a enum of Tuples in Swift?
I'd like to build something like:
enum ErrorCode: (Int, String) {
case Generic_Error = (0, "Unknown")
case DB_Error = (909, "Database")
}
But it doesn't compile...
'
ErrorCode
' declares raw type '(Int, String)
', but does not conform toRawRepresentable
and conformance could not be synthesizedRaw type '
(Int, String)
' is not expressible by a string, integer, or floating-point literal
RawRepresentable
conformance cannot be synthesized because raw type '(Int, String)
' is notEquatable
Is there a way to obtain a similar result?
Upvotes: 73
Views: 29446
Reputation: 522
This is what I did in a similar situation. Use an associated data enum, with default values (you can even name the values in the tuple if you like). Then add a simple function that returns the tuple based on self.
enum ErrorCode {
case Generic_Error( code: Int = 0, desc: String = "Unknown")
case DB_Error( code: Int = 909, desc: String = "Database")
func getCodeDescription() -> (Int, String) {
switch self {
case let .Generic_Error(code, desc): return (code, desc)
case let .DB_Error(code, desc): return(code, desc)
}
}
}
Later
var errorCode: Int
var errorDesc: String
let myError: ErrorCode = .DB_Error() // let it take the default values
(errorCode, errorDesc) = myError.getCodeDescription()
Upvotes: 0
Reputation: 11343
I think I would change your code to something like this:
enum ErrorCode {
case generic, db
var message: String {
switch self {
case .generic:
return "Unknown"
case .db:
return "Database"
}
}
var code: Int {
switch self {
case .generic:
return 0
case .db:
return 909
}
}
}
I feel this would make it much more easier to use like so:
let error = ErrorCode.generic
print("Error Code: \(error.code), Message: \(error.message)")
Upvotes: 3
Reputation: 1003
My solution to keep the enum, was to create the get method for the rawValue var:
enum LoadingType {
case poster
case movie
case refresh
var rawValue: (file: String, anim: String) {
get {
switch self {
case .movie:
return ("poster_loading", "LoadingView")
case .poster:
return ("loading", "LoadingView")
case .refresh:
return ("loading", "RefreshView")
}
}
}
}
With this code, you can even call each of your Tuple elements by a name:
self.type.rawValue.file
Upvotes: 4
Reputation: 4759
enum ErrorCode {
case Generic_Error
case DB_Error
public var code:Int{
switch self {
case .Generic_Error: return 0
case .DB_Error: return 909
}
}
public var name:String{
switch self {
case .Generic_Error: return "Unknown"
case .DB_Error: return "Database"
}
}
}
using:
let err:ErrorCode = .Generic_Error
print(err.code) //0
print(err.name) //Unknown
Upvotes: 2
Reputation: 4669
Create your enum
and add a var
of tuple type (String, String)
.
enum SomeType {
case type1
case type2
case type3
var typeNameAndDescription: (name: String, description: String) {
switch self {
case .type1:
return ("type1 name", "type1 description")
case .type2:
return ("type2 name", "type2 description")
case .type3:
return ("type3 name", "type3 description")
}
}
}
and later:
let myType = SomeType.type1
let typeName = myType.typeNameAndDescription.name
let typeDescription = myType.typeNameAndDescription.description
Upvotes: 18
Reputation: 726
You can conform to RawRepresentable
and use (Int, String)
as the Self.RawValue
associated type.
enum ErrorCode: RawRepresentable {
case Generic_Error
case DB_Error
var rawValue: (Int, String) {
switch self {
case .Generic_Error: return (0, "Unknown")
case .DB_Error: return (909, "Database")
}
}
init?(rawValue: (Int, String)) {
switch rawValue {
case (0, "Unknown"): self = .Generic_Error
case (909, "Database"): self = .DB_Error
default: return nil
}
}
}
Upvotes: 53
Reputation: 351
Create an Enumeration as Int.
For example:
https://github.com/rhodgkins/SwiftHTTPStatusCodes/blob/master/Sources/HTTPStatusCodes.swift
Upvotes: -4
Reputation: 19544
Swift enumerations cannot have Tuples as a raw value type.
Alternative approaches include storing the code and deriving a description from that:
enum ErrorCode: Int, CustomStringConvertible {
case Generic = 0
case DB = 909
var description: String {
switch self {
case .Generic:
return "Unknown"
case .DB:
return "Database"
}
}
}
...or storing associated values for code and description in the enumeration cases themselves:
enum Error {
case Generic(Int, String)
case DB(Int, String)
}
If you're just looking for constant values, @matt's suggestion of organizing them within a struct
would work, too.
Upvotes: 59
Reputation: 24031
you can do such thing, maybe:
enum ErrorCode {
case Generic_Error
case DB_Error
func values() -> (code: Int!, description: String?)! {
switch self {
case .Generic_Error:
return (0, "Unknown")
case .DB_Error:
return (909, "Database")
}
}
}
and you can do such thing later:
let errorCode: ErrorCode = ErrorCode.Generic_Error;
if (errorCode.values().code == 0) {
// do the business here...
}
Upvotes: 20
Reputation: 535880
It depends what you mean by "similar". What I do is use a Struct with static constant properties:
struct Trouble {
static let Generic_Error = (0, "Unknown")
static let DB_Error = (909, "Database")
}
Now things like Trouble.Generic_Error
are usable throughout your code.
Upvotes: 49