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
andintTarget
being initialized to appropriateEnum
cases, however, the stringTarget one turns out to benil
.
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
orString
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
How to Add Icon to a Share Sheet in Swift
How to Refresh Multiple Timers in Widget iOS14
Possible to Write Swift Println Logs into File Too
Referencing Self in Super.Init
Why I Can Not Use Equatable Function in My View When the View Can Use It in Swiftui
How to Combine Two Nsdictionary in Swift
Error: Extraneous Argument Label 'No1:' in Call
Generics and Functional Programming in Swift
Swift 5 Coredata Predicate Using Uuid
How to Pass Binding to Child View in the New Navigationstack.Navigationdestination
Swiftui Pass Two Child Views to View
Split String by Components and Keep Components in Place
Create Complicated Nscompoundpredicate in Swift 3
Rectangle Progress Bar Swiftui
Display Table View When Searchbar (From Searchcontroller) Begin Edited Swift