Constantes con const
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 14 de 57.
const val declara una constante en tiempo de compilación: un valor que queda fijado cuando se compila el programa. Se permite en el nivel superior de un archivo y dentro de un object o companion object, y solo para tipos básicos como Int, Double y Boolean, y para String:
const val MAX_PLAYERS = 4
class Lobby {
val players = mutableListOf<String>()
fun canStart() = players.size in MIN_PLAYERS..MAX_PLAYERS
companion object {
const val MIN_PLAYERS = 2
}
}Dentro de main:
val lobby = Lobby()
lobby.players += listOf("ada", "bo")
println(lobby.canStart())
println("${Lobby.MIN_PLAYERS}-$MAX_PLAYERS players")Salida:
true
2-4 playersLas constantes se nombran en UPPER_SNAKE_CASE. const es más estricto que val: el valor debe conocerse sin ejecutar ningún código, por lo que no se permite una llamada a una función ni una lista. Un val dentro de un objeto también se comparte y es de solo lectura, y acepta cualquier valor:
const val GREETING = "Hello" // un literal String
const val TIMEOUT_MS = 30 * 1000 // calculado a partir de literales
// const val START = System.nanoTime() // error: no es una constante
// const val DAYS = listOf("Mon", "Tue") // error: solo tipos básicos y String
object Defaults {
val DAYS = listOf("Mon", "Tue") // un val compartido de solo lectura
}Un objeto complementario también puede contener estado mutable compartido. Cada instancia lee y cambia la misma propiedad, lo que resulta adecuado para contadores y cachés. Esta clase mantiene una instancia por nombre, por lo que preguntar dos veces devuelve el mismo objeto (=== comprueba que dos referencias apuntan a un solo objeto):
class Tile private constructor(val name: String) {
companion object {
private val cache = mutableMapOf<String, Tile>()
val created: Int
get() = cache.size
fun of(name: String) = cache.getOrPut(name) { Tile(name) }
}
}Dentro de main:
val a = Tile.of("grass")
val b = Tile.of("grass")
Tile.of("water")
println(a === b)
println(Tile.created)Salida:
true
2¿De nivel superior o complementaria? Una constante o función de nivel superior pertenece a su archivo y se usa por su nombre simple en todos los archivos del paquete. Coloca una constante en un objeto companion cuando pertenece a una sola clase: quienes llaman escriben Lobby.MIN_PLAYERS, lo que indica de dónde proviene el valor, y una private const val permanece dentro de esa clase.
// Limits.kt
const val MAX_UPLOAD_MB = 25 // usado en todas partes como MAX_UPLOAD_MB
// Lobby.kt
class Lobby {
companion object {
const val MIN_PLAYERS = 2 // usado como Lobby.MIN_PLAYERS
private const val ROOM_PREFIX = "L-" // solo dentro de Lobby
}
}Desafío
FácilCompleta la clase Order(val item: String, val qty: Int). Su objeto companion contiene las constantes MAX_QTY = 10 y PREFIX = "ORD", un contador privado para el siguiente número de pedido, el total compartido de solo lectura totalItems y el count calculado de los pedidos creados. El bloque init requiere una cantidad entre 1 y MAX_QTY con el mensaje quantity must be 1-10 (construido a partir de la constante), después asigna al pedido su id ORD-001, ORD-002, ... y añade su cantidad a totalItems. label() devuelve ORD-001 tea x2.
El código proporcionado imprime max per order: 10, después lee las líneas tea 2 e imprime la etiqueta o el mensaje de error, y finalmente orders: 2, items: 5. Los pedidos rechazados no consumen un número.
Tu código va en Order.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
fun main() {
// Código de entrada/salida suministrado: déjalo como está
val input = generateSequence(::readLine).toList()
println("max per order: ${Order.MAX_QTY}")
for (line in input) {
val (item, qty) = line.split(" ")
try {
println(Order(item, qty.toInt()).label())
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
println("orders: ${Order.count}, items: ${Order.totalItems}")
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesConstructores primariosBloques init y validaciónConstructores secundariosRepaso - Tarjeta de biblioteca4Herencia
Clases abiertas y subclasesSobrescritura de miembrossuper y constructoresClases abstractasRepaso: directorio del personal2Propiedades y encapsulación
Accesores personalizadosModificadores de visibilidadSetters privadoslazy y lateinitRepaso: cuenta bancaria5Interfaces
Declaración de interfacesMétodos predeterminadosInterfaces múltiplesInterfaces como tiposRepaso: métodos de pago8Genéricos
Funciones genéricasClases genéricasRestricciones de tiposVariancia con in y outRepaso - Cola de prioridad11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de libros3Objetos y complementos
Declaraciones de objetosObjetos complementariosConstantes con constExpresiones de objetosRepaso: taquillaPractica por tu cuenta: Playground de Kotlin