11

I am not sure if I am clear with my title. In Swift I have this struct.

struct Movement {
 let name: String
 var reps: Int
}

let movement1 = Movement(name: "Push Ups", reps: 20)

var movementA = movement1
movementA.reps = 30

print(movement1.reps) // Prints 20
print(movementA.reps) // Prints 30

What is alternative in Kotlin (or Java)? The problem is that in my app I have a workout that consists of multiple movements. I append these movements to the MutableList and the problem appears when I have workout where a movement is repeated.

For example when I want to enter workout like:

20 Push Ups

30 Pull Ups

40 Push Ups

I end up with:

40 Push Ups

30 Pull Ups

40 Push Ups

At first, I select movement #1 and set reps of movement #1 but when I select movement #3 and set reps of movement #3 it overrides variables of movement #1.

Any idea?

I have tried something like this but it didn't work.

class Movement(name: String) {
 var reps: Int? = null
}
val movement1 = Movement("Push Ups")
movement1.reps = 20
var movementA = movement1
movementA.reps = 30
Log.i("REPS1: ", movement1.reps.toString()) // 30
Log.i("REPSA: ", movementA.reps.toString()) // 30
Ondřej Ševčík
  • 1,049
  • 3
  • 15
  • 31
  • Java has [```Object.clone()```](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()), which works (well, does something) on anything marked [```Cloneable```](https://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html). But I could not tell how this mechanism appears in Kotlin. – tevemadar Apr 11 '18 at 22:06
  • 1
    Why can't you just create a new instance of `Movement` instead of assigning it to another variable? – Sam Apr 11 '18 at 22:07
  • Java is a little weird in the way in handles copies, but here's some good SO threads on the topic: https://stackoverflow.com/questions/6182565/deep-copy-shallow-copy-clone and https://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java – Jacob Lange Apr 11 '18 at 22:08
  • That is because Class is reference type, whereas Struct is value type in Swift. I have never used Kotlin, though `data class` seems like the Struct for Kotlin from Bubletan's answer. – Zhou Haibo Oct 11 '22 at 05:20

2 Answers2

22

I have never used Swift, but it seems like you're having a mutable value which gets copied when you assign it to a new variable. In Kotlin, you cannot have such type. When you assign a value to a new variable, only the reference gets copied and it still points to the same exact memory location.

You could use a data class which gives you a convenient copy method:

data class Movement(val name: String, val reps: Int)

val movement1 = Movement("Push Ups", 20)
val movementA = movement1.copy(reps = 30)
Bubletan
  • 3,833
  • 6
  • 25
  • 33
4

First, let me cover why you have the same value for both movement1 and movementA. When you assign in Kotlin, you are copying a reference, not a class.

var movementA = movement1

So what that does is create a new variable called movementA and points it to the exact same object that movement1 is pointing to.

I think you probably want to look at data classes. They come with a copy constructor that might come in handy.

data class Movement(val name: String, val reps: Int)

And then you can create them off of each other, like in the swift code you show above.

val movement1 = Movement("Push-Ups", 20)
val movementA = movement1.copy(reps = 30)

Or you could make the properties vars instead of vals and mutate them directly...

data class Movement(var name: String, var reps: Int)
var movement1 = Movement("Push-Ups", 20)
var movementA = movement1.copy()
movementA.reps = 30
Todd
  • 30,472
  • 11
  • 81
  • 89