Soy consciente de que un argumento pasado a una función se verá como "val", incluso si la variable se inicializó como "var". Pero esto ha sido un problema para mí. En este código de ejemplo a continuación, quiero modificar el valor de la variable "num" usando la función "changeNum". Pero, por supuesto, Kotlin no me permitirá modificarlo. ¿Cómo soluciono esto? ¿Cómo puedo usar la función "changeNum" para modificar la variable "num"?
fun main() { var num: Int = 5 changeNum(num) } fun changeNum(num: Int){ num += 2 print(num) }Kotlin se pasa por valor, por lo que no puede hacerlo directamente con tipos primitivos como Int .
El enfoque habitual es simplemente devolver un nuevo valor en lugar de modificar lo que recibe como argumento (un enfoque funcional). Lo hace más claro desde la perspectiva del código de llamada:
fun main() { var num: Int = 5 num = changeNum(num) } fun changeNum(num: Int): Int { val newValue = num + 2 print(newValue) return newValue }Si realmente desea mutar la variable en lugar de devolver un nuevo valor, aquí hay 2 enfoques en los que estoy pensando para hacer esto:
La opción 1 se vería así:
class SomeClass(var num: Int) { fun changeNum() { num += 2 print(num) } } fun main() { val container = SomeClass(5) container.changeNum() }La opción 2 se vería así:
class SomeMutableContainer(var num: Int) fun main() { val container = SomeMutableContainer(5) changeNum(container) } fun changeNum(container: SomeMutableContainer) { container.num += 2 print(container.num) }Es posible hacer esto en Kotlin con una propiedad
import kotlin.reflect.KMutableProperty0 var num = 1 fun main() { println(num) changeNum(::num) println(num) } fun changeNum(numProperty: KMutableProperty0<Int>) { numProperty.set(12345) } >> 1 >> 12345 Una KMutableProperty0 representa una var básica, por lo que puede pasar una referencia de propiedad utilizando la sintaxis ::num (igual que pasaría una referencia de función). De esa manera, en lugar de pasar el valor actual, está proporcionando a la función una referencia a la propiedad en sí, y luego puede llamar a set en ella.
Pero la pregunta es, ¿realmente quieres hacer esto? ¿O está complicando demasiado algo que debería hacerse de una manera más simple o más legible? En realidad, no puedes hacer esto con una variable , como si estuvieras tratando de hacerlo dentro de fun main() , solo propiedades en un objeto (vars de nivel superior, básicamente), pero incluso si pudieras, ¿por qué no lo harías? hacer esto en su lugar?
fun main() { var num: Int = 5 ... num = changeNum(num) // this would need renaming but y'know } sigue siendo una llamada de una línea, su función changeNum aún puede tener efectos secundarios, validar, etc., simplemente devuelve el resultado en lugar de configurarlo como un efecto secundario. Esto es mucho más fácil de seguir, especialmente cuando es la forma habitual de establecer un valor en una cosa.
Si realmente quiere usar referencias, pero hacerlas de nivel superior en su clase es complicado, entonces tal vez considere crear un objeto de estado en su lugar:
import kotlin.reflect.KMutableProperty0 data class AllThemNums(var num1 :Int = 1, var num2: Int = 9999) fun main() { val nums = AllThemNums(num1 = 5) changeNum(nums::num1) println(nums) } fun changeNum(numProperty: KMutableProperty0<Int>) { numProperty.set(numProperty.get() + 2) } >> AllThemNums(num1=7, num2=9999) ¡incluso podría poner la función changeNum dentro de la clase de datos!