Lançado · em melhoria
Guia de Kotlin · 3/6
Por enquanto, este capítulo está disponível apenas em inglês.
This chapter covers basic types, collections, and the kinds of classes Kotlin offers for modeling data.
Numbers behave like objects with methods, yet the compiler maps them to JVM primitives wherever it can.
| Type | Size | Example |
|---|---|---|
Int | 32-bit | 42 |
Long | 64-bit | 3_000_000_000L |
Double | 64-bit float | 0.75 |
Float | 32-bit float | 9.99f |
Boolean | true or false | true |
Char | one character | 'K' |
String | text | "Kotlin" |
fun main() {
val count = 42 // Int
val big = 3_000_000_000L // Long; underscores group digits
// val wide: Long = count // error: no implicit widening
val wide: Long = count.toLong()
println(wide + big)
println("42".toInt() + 1) // 43
println("abc".toIntOrNull()) // null instead of an exception
}Unlike Java, an Int is never silently widened to a Long; convert explicitly with toLong(), toDouble() and friends.
Collection interfaces come in pairs: read-only List, Set and Map, and their MutableList, MutableSet and MutableMap counterparts. listOf gives you no add; use mutableListOf when you need to change the contents.
fun main() {
val numbers = listOf(3, 1, 4, 1, 5) // List<Int>
val unique = setOf("a", "b", "a") // Set<String>: [a, b]
val ages = mapOf("Sam" to 31, "Ana" to 28) // Map<String, Int>
val todo = mutableListOf("groceries")
todo.add("gym")
todo.removeAt(0)
val scores = mutableMapOf<String, Int>()
scores["kim"] = 90
scores["lee"] = 85
println(numbers.filter { it > 2 }.map { it * 10 }) // [30, 40, 50]
println(numbers.sorted().distinct()) // [1, 3, 4, 5]
println(unique.size) // 2
println(ages.getOrDefault("Max", 0)) // 0
println(todo) // [gym]
}to is an infix function that builds a Pair. Read-only means the interface has no mutators, not that the object can never change. Expose read-only types and keep mutation inside the owning code.
The parentheses after a class name declare its primary constructor, and marking a parameter val or var turns it into a property. There is no new keyword. Classes and members are final by default, so you must mark them open to allow inheritance.
open class Animal(val name: String) {
open fun sound(): String = "..."
override fun toString() = "$name: ${sound()}"
}
class Dog(name: String, var age: Int) : Animal(name) {
init {
require(age >= 0) { "age must not be negative" }
}
val isPuppy: Boolean
get() = age < 1 // computed on every read
override fun sound() = "Woof"
}
fun main() {
val dog = Dog("Rex", 3)
dog.age += 1
println(dog) // Rex: Woof
println(dog.isPuppy) // false
}init blocks run during construction, and properties can have custom getters and setters.
For classes whose job is holding values, use data class. The compiler generates equals, hashCode, toString, copy and the componentN functions behind destructuring.
data class User(val id: Long, val name: String, val email: String? = null)
fun main() {
val a = User(1, "Sam")
val b = User(1, "Sam")
println(a == b) // true: compares property values
println(a) // User(id=1, name=Sam, email=null)
val renamed = a.copy(name = "Sammy")
val (id, name) = renamed // destructuring
println("$id $name") // 1 Sammy
}== calls equals; use === for reference identity. The ? in String? marks a nullable type, covered in chapter 6.
Use enum class for a fixed set of constants. When each case carries different data, use a sealed class or interface: its subtypes must live in the same module and package, so the compiler can check that a when is exhaustive.
import kotlin.math.PI
enum class Color(val hex: String) {
RED("#FF0000"), GREEN("#00FF00"), BLUE("#0000FF");
fun label() = name.lowercase()
}
sealed interface Shape
data class Circle(val radius: Double) : Shape
data class Rect(val width: Double, val height: Double) : Shape
data object Empty : Shape
fun area(shape: Shape): Double = when (shape) { // no else needed
is Circle -> PI * shape.radius * shape.radius
is Rect -> shape.width * shape.height
Empty -> 0.0
}
fun main() {
println(Color.entries.map { it.label() }) // [red, green, blue]
println(area(Rect(2.0, 3.0))) // 6.0
}An object declaration defines a singleton. Kotlin has no static, so class-level factories and constants go in a companion object.
object AppConfig {
var debug = false
fun summary() = "debug=$debug"
}
class Temperature private constructor(val celsius: Double) {
companion object {
val FREEZING = Temperature(0.0)
fun fromFahrenheit(f: Double) = Temperature((f - 32) * 5 / 9)
}
}
fun main() {
AppConfig.debug = true
println(AppConfig.summary()) // debug=true
println(Temperature.fromFahrenheit(212.0).celsius) // 100.0
println(Temperature.FREEZING.celsius) // 0.0
}toLong() and similar.listOf) and mutable (mutableListOf) variants.final by default, and val/var constructor parameters become properties.equals, toString, copy and destructuring for free.enum or sealed; use object for singletons and companion object instead of statics.
0 comentários
Fazer login · Faça login para deixar um comentário.
Seja o primeiro a comentar.