Enum's Rawvalue Property Not Recognized

enum's rawValue property not recognized

Martin's answer is completely right.

Here is a different view that more directly answers your question.

In Xcode 6.0, an enum doesn't have a rawValue property. rawValue was added in Xcode 6.1 but note that it is a read-only computed property, so you can't assign to it in Xcode 6.1 either.

In Xcode 6.1, it is unnecessary to implement an initializer that takes a rawValue because that has already been provided natively by the language. If you were trying to imitate that behavior in Xcode 6.0, then you might try something like:

enum Rank: String
{
case One = "One", Two="Two"

init(rawValue : String)
{
self = Rank.fromRaw(rawValue)
}
}

but the problem with this is that fromRaw returns an optional enum value because the rawValue string might correspond to any enum value.

So what do you do at this point? You could add a ! to force unwrap the value:

self = Rank.fromRaw(rawValue)!

but this would crash if you tried to create an enum with an invalid raw value.

You could treat one of the enum values as a default and use the nil coalescing operator ?? to safely unwrap it:

self = Rank.fromRaw(rawValue) ?? One

which would avoid a crash, but would probably lead to unexpected behavior on the part of your program.

What you can't do in Xcode 6.0 is have the init return an optional value. This capability was added in Xcode 6.1 and it was exactly this new capability that allowed them to change fromRaw() from a function in Xcode 6.0 to an optional initializer in Xcode 6.1.

Using Class as RawValue of Enum not working

The errors you get are mostly about the way you incorrectly declared your initialisers. They don't really have much to do with creating an enum with a class raw value.

Because your initialisers are required by the protocol, they need to be marked as required. You don't need to do this if your class is final. So either mark the class as final or mark all the initialisers as required.

The two convenience initialisers need to be marked as convenience:

public convenience init(unicodeScalarLiteral value: String) {
self.init(stringLiteral: value)
}
public convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}

These are "convenience" initialisers because they call another initialiser declared in the class.

Additionally, the public init(stringLiteral value: String) initialiser does not initialise all the properties. Think about what happens if the if statements are not run. You need to give your properties (height, identifier and type) some default values.

Replace enum's rawValue property with a custom operator

Hei man, you are really lazy! ;-)

postfix operator .. { }

postfix func ..<T: RawRepresentable> (lhs: T) -> T.RawValue {
return lhs.rawValue
}

There's a protocol for that :-)

Anyway beware not introducing too much esoteric custom operators ;-)

How to get enum from raw value in Swift?

Too complicated, just assign the raw values directly to the cases

enum TestEnum: String {
case Name = "Name"
case Gender = "Gender"
case Birth = "Birth Day"
}

let name = TestEnum(rawValue: "Name")! //Name
let gender = TestEnum(rawValue: "Gender")! //Gender
let birth = TestEnum(rawValue: "Birth Day")! //Birth

If the case name matches the raw value you can even omit it

enum TestEnum: String {
case Name, Gender, Birth = "Birth Day"
}

In Swift 3+ all enum cases are lowercased

Swift remove .rawValue from enums

If your only use of the enum values is so they can be used as String constants, you should change your code to use a struct with static values.

struct DMED {
static let money = "DMMoney"
static let netWorth = "DMNetWorth"
static let businessNum = "DMBusinessNum"
static let generalEPM = "DMGeneralEPM"
static let generalThreat = "DMGeneralThreat"
}

required init?(coder aDecoder: NSCoder) {
self.money = (aDecoder.decodeDouble(forKey: DMED.money))
self.netWorth = (aDecoder.decodeDouble(forKey: DMED.netWorth))
self.businessNum = (aDecoder.decodeInteger(forKey: DMED.businessNum))
self.generalEPM = (aDecoder.decodeInteger(forKey: DMED.generalEPM))
self.generalThreat = (aDecoder.decodeInteger(forKey: DMED.generalThreat))
}

Switch : Enum Switch issue : Not member of a int

You have to declare contactViewMode as ContactViewMode and not Int.

If you really want it to be Int, then you have to change the cases in your switch, by comparing the variable to the rawValue property of the enum cases:

switch contactViewMode {
case ContactViewMode.ViewModeFavourite.rawValue:
contacts = DBManager.getFavouriteContacts() as [ContactEntity]
case ContactViewMode.ViewModeRecent.rawValue:
contacts = DBManager.getFavouriteContacts() as [ContactEntity]
default:
contacts = DBManager.getAllContacts() as [ContactEntity]
}

but unless you have a good reason for that, I wouldn't recommend

Swift enum with custom initializer loses rawValue initializer

This bug is solved in Xcode 7 and Swift 2

Swift enum custom raw type not expressible by different literals

Solving your Question

What I expected the above code to produce is both stringTarget and intTarget being initialized to appropriate Enum cases, however, the stringTarget one turns out to be nil.

They aren't nil. They are this: ""

This happens because both the .content and .resources cases are not explicitly defined by a String. And because of this, they both take the ExpressibleByIntegerLiteral route, and are hence defined as this ""

init(integerLiteral: Int) {
string = "" // see
int = integerLiteral
}


Solved for Int

Use this fancy method in place of IntValue(rawValue: 1):

func IntValue(_ this: Int) -> String? {
return Target(rawValue: 0) != nil ? String(describing: Target(rawValue: 0)!) : nil
}


Solved for String

First, conform your enum to CaseIterable, like so:

enum Target: Path, CaseIterable {

Next, use this fancy method in place of Target(rawValue: "content"):

func StringValue(_ this: String) -> String? {
return Target.allCases.contains { this == String(describing: $0) } ? this : nil
}


Truly solved for String

Now, I've removed a crucial bug where case foo = "bar" can be found both as 'foo' or 'bar'. If you don't want this, use this code instead:

func StringValue(_ this: String) -> String? {
var found: String? = nil
_ = Target.allCases.filter {
if let a = Target(rawValue: Path.init(string: this, int: 0)) {
found = String(describing: a)
return this == String(describing: a)
}
found = String(describing: $0)
return this == String(describing: $0)
}
return found
}


Custom Raw Values for Enums

Here's a quick tutorial:

I am wondering if enum can conform it's rawValue to the ClosedRange struct, just like it can conform to String.

enum Foo: ClosedRange<Int> {
case bar = 1...4
}

Obviously this is not an option, since 1...4 is not a literal

This seems to work:

enum Foo: ClosedRange<Int> {
case foo = "1...3"
case bar = "1...4"
func overlaps(_ with: Foo) -> Bool { return self.rawValue.overlaps(with.rawValue) }
}
extension ClosedRange: ExpressibleByStringLiteral {
public typealias StringLiteralType = String
public init(stringLiteral value: String) {
let v = value.split(separator: ".")

switch Bound.self {
case is Int.Type: self = (Int(v[0])! as! Bound)...(Int(v[1])! as! Bound)
default: fatalError()
}
}
}

It allows you to do this:

print(Foo.foo.overlaps(Foo.bar))
  • You can add more types like Double or String using this technique

Side Note: My attempt allows for non-unique rawValues (SR-13212) which is a shame. But I'm not thinking that is fixable:

enum Foo: ClosedRange<Int> {
case foo = "1...3"
case bar = "1...4"
case bar = "1...04" // Duplicate, but Swift allows it.
}


Enum Case not found in type

Yes, Because your let op = Operator(rawValue: symbol) is optional and in switch case your are matching exact values. So you can apply optional in case while comparing. as like below.

func isOperator(_ symbol: Character)-> Operator? {
let op = Operator(rawValue: symbol)
switch op {
case .Substract?, .Add?, .Multiply?, .Divide?:
return op
default:
return nil
}
}


Related Topics



Leave a reply



Submit