Digamos que tengo una variable:
var myObject : MyObject? = null
debe ser borrado en algún lugar:
myObject?.clear myObject = nully debe ser definitivamente no anulable en un lugar de uso. En Java puedo hacer algo como esto:
private MyObject getMyObject(){ if(myObject == null) { myObject = new MyObject() } return myObject }La pregunta: ¿Cómo puedo lograr eso en Kotlin?
Encontré una sugerencia para usar elvis-operator:
private fun getMyObject() = myObject ?: MyObject() pero eso no asigna un resultado (si se creara una nueva instancia de MyObject ) a la variable myObject . Por favor ayúdenme con la solución y la explicación. gracias de antemano
El problema es que el getter y setter de una propiedad no pueden tener diferentes tipos. Sugeriría una propiedad privada anulable separada y un método para borrarla:
private var _myObject: MyObject? = null var myObject: MyObject // or val, depending get() { if (_myObject == null) { _myObject = MyObject() } return _myObject!! } set(value: MyObject) { _myObject?.clear() _myObject = value } fun clearMyObject() { _myObject?.clear() _myObject = null }Si necesita este patrón más de una vez, escriba un delegado .
Puede utilizar el campo de respaldo de la propiedad.
class Foo { var bar: String? = null get() { if (field == null) { field = "Automatically set" } return field } }Intentarlo:
fun main() { val foo = Foo() foo.bar = "Manually set" println(foo.bar) foo.bar = null println(foo.bar) } Desafortunadamente, la propiedad debe ser anulable para que esto funcione. Tendrás que usar !! o ?. En todas partes.
También podría utilizar un delegado. Esto requiere más código para escribir la propiedad, pero facilita el uso de la propiedad en otros lugares.
class Foo(initBar: String? = null) { private val barDelegate = NullDelegate(initBar) { "Automatically set" } var bar: String by barDelegate // not nullable to outside world fun clearBar() { barDelegate.clear() } } // Reusable. Not thread-safe. class NullDelegate<T>( private var value: T? = null, private val supplier: () -> T ) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T { if (value == null) value = supplier() return value!! } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { this.value = value } fun clear() { value = null } } Para establecer la bar en null , llamaría a foo.clearBar() en lugar de foo.bar = null .
Puede combinar el enfoque similar a Java con el uso del operador Elvis, escribiendo algo como esto:
private fun getMyObject() : MyObject { myObject = myObject ?: MyObject() return myObject as MyObject } La conversión explícita as MyObject es necesaria debido a la declaración de myObject : var myObject MyObject? = null . myObject es un MyObject anulable pero el tipo de retorno de getObject es MyObject . ¡Espero que esto pueda ayudarte!