How to Change an Associated Value Within an Enum

Can I change the Associated values of a enum?

Your most immediate problem is that you're attempting to change the value of an immutable variable (declared with let) when you should be declaring it with var. This won't solve this particular problem though since your name variable contains a copy of the associated value, but in general this is something that you need to be aware of.

If you want to solve this, you need to declare the adjust() function as a mutating function and reassign self on a case by case basis to be a new enum value with an associated value composed from the old one and the new one. For example:

enum SimpleEnum{
case big(String)
case small(String)
case same(String)

mutating func adjust() {
switch self{
case let .big(name):
self = .big(name + "not")
case let .small(name):
self = .small(name + "not")
case let .same(name):
self = .same(name + "not")
}
}
}

var test = SimpleEnum.big("initial")
test.adjust()

switch test {
case let .big(name):
print(name) // prints "initialnot"
case let .small(name):
print(name)
case let .same(name):
print(name)
}

Is it possible to change an associated value within an enum?

Rob Napier's answer is fine but I have a different understanding of your question. I would have written something like this instead:

enum MyEnum {

case SomeCase(Int?)

mutating func someFunc() {
switch self {
case .SomeCase(.Some(_)):
self = .SomeCase(5)
default:
// or case .SomeCase(.None): if you prefer
break
}
}

}

With this code, the enum is mutated with someFunc if and only if its associated value is not nil. Thus, I have the following results while testing in a Playground (results appear as comments):

var x = MyEnum.SomeCase(nil)

switch x {
case .SomeCase(.Some(let a)):
println(a)
default:
println("Associated value is nil") // Will print "Associated value is nil"
}

x = MyEnum.SomeCase(20)
x.someFunc()

switch x {
case .SomeCase(.Some(let a)):
println(a) // Will print 5
default:
println("Associated value is nil")
}

Changing associated value of enum Swift

You can only assign a new enumeration value to the variable.
As in Can I change the Associated values of a enum?,
the associated values of the current values can be retrieved in a switch statement,
with a case pattern which binds the associated value to a local variable.

The currently associated filtered value is not needed, therefore
we can use a wildcard pattern _ at that position.

Since var gameOrigin: Origin? is an optional, we need an “optional pattern” with a trailing question mark.

switch gameOrigin {
case .search(let searchTerm, _)?:
gameOrigin = .search(searchTerm: searchTerm, filtered: filtered)
default:
break
}

The same can be done also in an if-statement with case and pattern
matching:

if case .search(let searchTerm, _)? = gameOrigin {
gameOrigin = .search(searchTerm: searchTerm, filtered: filtered)
}

Change Value of associated enum

I think I finally figured out how to do this with a set for the computed property

var info: TextFieldInfo { 
get {
switch self {
case .generic(let type, let title):
return (type, title, "")
case .entry(let type, let title, let entry):
return (type, title, entry)
}
}
set {
switch self {
case .generic:
self = TextFieldModelEnum.generic(type: newValue.type, title: newValue.title)
case .entry:
self = TextFieldModelEnum.entry(type: newValue.type, title: newValue.title, entry: newValue.entry)
}
}
}

Example

var tf = TextFieldModelEnum.entry(type: .text, title: "A Title", entry: "An Entry")
print(tf.info.entry)
print(tf.info.title)
tf.info.entry = "new entry"
print(tf.info.entry)
tf.info.title = "new title"
print(tf.info.title)

Output

An Entry

A Title

new entry

new title

Binding to an associated value of an enum

You can extend your enumeration and add a text property with a getter and a setter:

extension Choice {
var text: String {
get {
switch self {
case let .one(string): return string
case let .two(string): return string
}
}
set {
switch self {
case .one: self = .one(newValue)
case .two: self = .two(newValue)
}
}
}
}

Then you can simply pass the text property:

TextField("", text: $choice.text) 

How to change an enum value in Java?

You can add the turnLeft/ turnRight methods directly inside the enum.

enum Direction{
UP, RIGHT, DOWN, LEFT;

public Direction turnLeft() {
switch(this) {
case UP: return LEFT;
case RIGHT: return UP;
case DOWN: return RIGHT;
default: return DOWN; // if you leave the LEFT case, you still need to return something outside the block on some Java versions
}
}
}

and then whenever you want to make a turn, you can assign the "left" value to the direction variable.

private Direction direction = Direction.DOWN;

public void turnAndPrint() {
direction = direction.turnLeft();
System.out.println(direction.name()); // will print RIGHT when called the first time
}

Mutate a value-type associated value in-place

It's not possible to change an enum associated value, without overwriting the enum itself; if instead S is declared as class, it's a quite trivial task.

Anyway I did some experiments that I report here:

1) based on withUnsafeMutablePointer:

var e = E.s(S(a: 1))
withUnsafeMutablePointer(to: &e, {
$0.pointee = E.s(S(a: 2))
})
print(e)

2) declaring a mutating func for overwriting implicitly the enum

struct S {
var a = 1
}

enum E {
case s(S)
mutating func setS(val:S) { self = E.s(val) }
}

var e = E.s(S(a: 1))
e.setS(val: S(a: 2))
print(2)

3) if S is a class:

class S:CustomDebugStringConvertible {
var a = 1
var debugDescription: String { return "\(a)" }
}

enum E {
case s(S)
}

let e = E.s(S())
if case let .s(s) = e {
s.a = 2
}
print(e)

Change ENUM's value inside the ENUM class function using this in JAVA

You can't change an enum to another enum. You can however update an enum variable to refer to another enum value.

public enum Entry {
X,
O;

public Entry switchEntry() {
return (this == X ? O : X);
}
}
Entry e = Entry.X;

e = e.switchEntry();


Related Topics



Leave a reply



Submit