Costanti con const
Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 14 di 57.
const val dichiara una costante in fase di compilazione: un valore che viene fissato quando il programma viene compilato. È consentita al livello superiore di un file e all'interno di un object o di un companion object, e solo per tipi di base come Int, Double e Boolean, e per 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
}
}All'interno di main:
val lobby = Lobby()
lobby.players += listOf("ada", "bo")
println(lobby.canStart())
println("${Lobby.MIN_PLAYERS}-$MAX_PLAYERS players")Output:
true
2-4 playersLe costanti hanno un nome in MAIUSCOLO_CON_UNDERSCORE. const è più restrittivo di val: il valore deve essere noto senza eseguire codice, quindi non sono consentite chiamate a funzioni o liste. Anche un val in un oggetto è condiviso e di sola lettura, e può accettare qualsiasi valore:
const val GREETING = "Hello" // un valore letterale String
const val TIMEOUT_MS = 30 * 1000 // calcolato a partire da valori letterali
// const val START = System.nanoTime() // errore: non è una costante
// const val DAYS = listOf("Mon", "Tue") // errore: sono ammessi solo i tipi di base e String
object Defaults {
val DAYS = listOf("Mon", "Tue") // un val condiviso di sola lettura
}Un oggetto companion può anche contenere uno stato mutabile condiviso. Ogni istanza legge e modifica la stessa proprietà, il che è adatto a contatori e cache. Questa classe mantiene un’unica istanza per nome, quindi richiedendola due volte restituisce lo stesso oggetto (=== verifica che due riferimenti puntino a un unico oggetto):
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) }
}
}All’interno di main:
val a = Tile.of("grass")
val b = Tile.of("grass")
Tile.of("water")
println(a === b)
println(Tile.created)Output:
true
2Di livello superiore o nel companion? Una costante o una funzione di livello superiore appartiene al suo file e viene usata con il suo nome semplice in ogni file del pacchetto. Inserisci una costante in un companion quando appartiene a una sola classe: chi la richiama scrive Lobby.MIN_PLAYERS, indicando da dove proviene il valore, e un private const val rimane all'interno di quella classe.
// Limits.kt
const val MAX_UPLOAD_MB = 25 // usato ovunque come MAX_UPLOAD_MB
// Lobby.kt
class Lobby {
companion object {
const val MIN_PLAYERS = 2 // usato come Lobby.MIN_PLAYERS
private const val ROOM_PREFIX = "L-" // solo all'interno di Lobby
}
}Sfida
FacileCompleta la classe Order(val item: String, val qty: Int). Il suo oggetto companion contiene le costanti MAX_QTY = 10 e PREFIX = "ORD", un contatore privato per il numero del prossimo ordine, il totale condiviso di sola lettura totalItems e il valore calcolato count degli ordini creati. Il blocco init richiede una quantità compresa tra 1 e MAX_QTY con il messaggio quantity must be 1-10 (generato dalla costante), poi assegna all'ordine il suo id ORD-001, ORD-002, ... e aggiunge la sua quantità a totalItems. label() restituisce ORD-001 tea x2.
Il codice fornito stampa max per order: 10, poi legge le righe tea 2 e stampa l'etichetta o il messaggio di errore, e infine orders: 2, items: 5. Gli ordini rifiutati non consumano un numero.
Il tuo codice va in Order.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
fun main() {
// Codice di input/output fornito: lascialo così com'è
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}")
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiCostruttori primariBlocchi init e convalidaCostruttori secondariRiepilogo - Tessera della biblioteca4Ereditarietà
Classi aperte e sottoclassiRidefinizione dei membrisuper e costruttoriClassi astratteRiepilogo - Elenco del personale2Proprietà e incapsulamento
Accessor personalizzatiModificatori di visibilitàSetter privatilazy e lateinitRipasso - Conto bancario5Interfacce
Dichiarare le interfacceMetodi predefinitiInterfacce multipleLe interfacce come tipiRiepilogo - Metodi di pagamento8Tipi generici
Funzioni genericheClassi genericheVincoli sui tipiVarianza con in e outRiepilogo - Coda con priorità11Progetto: Gestione della biblioteca
Libri e sociPrendere in prestito i libri3Oggetti e companion
Dichiarazioni di oggettiOggetti companionCostanti con constEspressioni oggettoRipasso - BiglietteriaEsercitati da solo: Playground Kotlin