柚子快報(bào)邀請(qǐng)碼778899分享:Kotlin基本語法
柚子快報(bào)邀請(qǐng)碼778899分享:Kotlin基本語法
kotlin基本語法官網(wǎng)
1. 變量
‘val’ 聲明 僅被賦值一次的變量,初始化后不能重新賦值。 ‘var’ 聲明 可以重新分配的變量,可以在初始化后更改其值。
Kotlin 支持類型推斷,可以省略變量名后的類型。
val x: Int = 5
var x: Int = 5
val x = 5
變量只有在初始化后才能使用。 先聲明變量,然后再初始化,這種情況必須指定數(shù)據(jù)類型。
val c: Int
c = 3
2. 函數(shù)
'=' 代表 花括號(hào)。【特別之處】
fun sum(a: Int, b: Int) = a + b
‘Unit’ 類型 代表該函數(shù)沒有返回值
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
函數(shù)返回值也可以省略
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
3.類
類的屬性可以在其聲明或主體中列出?!咎貏e之處】
// 這種寫法 類似于 函數(shù)寫法
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
構(gòu)造函數(shù) 主構(gòu)造函數(shù) 次構(gòu)造函數(shù) 默認(rèn)構(gòu)造函數(shù)繼承 ‘open’ 標(biāo)記 一個(gè)類可被繼承。
4.字符串
‘$’ 在字符串中用于字符串模板的插值,這允許將 變量或表達(dá)式的值 插入到字符串中。這種特性被稱為‘字符串模板’。''用于表示單個(gè)字符的字符常量,""用于表示字符串,它可以包含多個(gè)字符?!咎貏e之處】
5.數(shù)組 和 列表
【特別之處】
數(shù)組:
需要明確指定元素類型。不可變長(zhǎng)度。
列表:
可以包含不同類型的元素,但建議保持列表元素類型的一致性。不可變列表 和 可變列表。
6.循環(huán)
for循環(huán)
for (item in items) {
println(item)
}
while 循環(huán)
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
7.when 表達(dá)式
【特別之處】 when 表達(dá)式 與 其他語言中的 switch-case有相似之處,但也有很多不同點(diǎn)。
when 表達(dá)式更加靈活。它可以接受各種類型的參數(shù),包括區(qū)間、類型判斷等,而不僅僅局限于整數(shù)或枚舉類型等特定類型。
// 區(qū)間判斷
when (num) {
in 1..5 -> println("Number is between 1 and 5.")
else -> println("Number is outside these ranges.")
}
// 類型判斷
when (obj) {
is Int -> println("It's an integer.")
is String -> println("It's a string.")
is Double -> println("It's a double.")
else -> println("Unknown type.")
}
//任意表達(dá)式作為條件
val str = "Hello"
when {
str.length > 5 -> println("String is long.")
str.length < 5 -> println("String is short.")
else -> println("String is just right.")
}
8.區(qū)間
【特別之處】 區(qū)間內(nèi) 用 ‘in’ 區(qū)間外 用 ‘!in’ ‘a(chǎn)..b’ 表示閉區(qū)間[a,b]
// 檢測(cè)某個(gè)數(shù)字是否在指定區(qū)間內(nèi)
if (x in 1..6) {
println("fits in range")
}
// 區(qū)間迭代
for (x in 1..5) {
println(x)
}
// 數(shù)列迭代 【特別之處】
for (x in 1..10 step 2) {
print(x) // 1、3、5、7、9
}
for (x in 9 downTo 0 step 3) {
print(x) // 9、6、3、0
}
9.Lambda 表達(dá)式
可以理解為一種簡(jiǎn)潔的、可以作為參數(shù)傳遞或者作為函數(shù)結(jié)果返回的匿名函數(shù)。
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.uppercase() }
.forEach { println(it) }
10.支持空安全
(類似于Dart)
寫法: 1.變量類型: Int? 2.‘?:’ 用來進(jìn)行空值判斷并提供一個(gè)默認(rèn)值,類似于Dart中的‘??’。 files?.size ?: "empty"
11.類型檢測(cè)與自動(dòng)類型轉(zhuǎn)換
‘is’ 操作符檢測(cè)一個(gè)表達(dá)式是否為某類型的一個(gè)實(shí)例。
if (obj is String) {
// `obj` 在該條件分支內(nèi)自動(dòng)轉(zhuǎn)換成 `String`
return obj.length
}
12.延遲屬性
使用‘by lazy’通常是在屬性聲明的地方,后面跟著一個(gè) lambda 表達(dá)式來計(jì)算屬性的值。
僅在首次訪問時(shí)計(jì)算。一旦屬性被初始化,后續(xù)的訪問將直接返回已初始化的值,不會(huì)再次執(zhí)行初始化的代碼。
【對(duì)比】 與Dart語言中的late還不太一樣,late表示該變量將在稍后被初始化。
Kotlin 的by lazy是線程安全的;Dart 的late變量不是自動(dòng)線程安全的。
val p: String by lazy {
println("Calculating string...")
"This is a lazy-evaluated string."
}
println("Before accessing p.")
println(p)
println("After accessing p.")
println(p) // 再次訪問不會(huì)重新計(jì)算
13.擴(kuò)展函數(shù)
fun 接收者類型.擴(kuò)展函數(shù)名(參數(shù)列表): 返回類型 { // 函數(shù)體 }
類似于Dart語言中的extension…on
// 擴(kuò)展函數(shù)
fun String.spaceToCamelCase() { …… }
// 調(diào)用
"Convert this to camelcase".spaceToCamelCase()
14.伴生對(duì)象
【特別之處】 companion object{ … }
1.定義'方法'和'屬性',可以’通過類名直接訪問’。(類似于其他語言中的靜態(tài)成員) 2.在類加載時(shí)'只會(huì)創(chuàng)建一次'。(可以實(shí)現(xiàn)單例) 3.包含初始化塊init{ … } ,對(duì)于需要在類加載時(shí)進(jìn)行的初始化操作非常有用。 4.可以添加拓展(MyClass.Companion.擴(kuò)展函數(shù)名)。
class MyClass {
companion object {
// 靜態(tài)屬性或方法
val someProperty: String = "This is a companion object property."
fun someMethod() {
println("This is a companion object method.")
}
// 初始化塊(會(huì)優(yōu)先執(zhí)行)
init {
println("Companion object initialized.")
}
}
}
// 為伴生對(duì)象添加拓展
fun MyClass.Companion.someExtensionFunction() {
println("This is an extension function for the companion object.")
}
// 調(diào)用
fun main() {
println(MyClass.someProperty)
MyClass.someExtensionFunction()
}
15.單例
對(duì)象聲明方式 ‘object’ 聲明單例
object Singleton {
val someProperty: String = "This is a singleton property."
fun someFunction() {
println("This is a singleton function.")
}
}
懶漢式單例(使用委托屬性)
class SingletonLazy private constructor() {
companion object {
// 首次訪問SingletonLazy.instance時(shí)才會(huì)創(chuàng)建實(shí)例
val instance: SingletonLazy by lazy { SingletonLazy() }
}
}
餓漢式單例
class SingletonEager private constructor() {
companion object {
// 在類加載時(shí)就創(chuàng)建實(shí)例(僅創(chuàng)建一次)
val instance = SingletonEager()
}
}
16.值類
'@JvmInline’注解作用 :
性能優(yōu)化。 在 Java 虛擬機(jī)(JVM)運(yùn)行時(shí),帶有@JvmInline注解的值類實(shí)例不會(huì)像普通的類對(duì)象那樣占用額外的內(nèi)存空間和帶來對(duì)象創(chuàng)建的開銷。它會(huì)更像直接使用那個(gè)字符串本身,從而提高程序的性能。簡(jiǎn)潔性和可讀性。只有 JVM 后端才需要該注釋。
@JvmInline
value class EmployeeId(private val id: String)
class Employee(val name: String, val employeeId: EmployeeId)
fun main() {
// 創(chuàng)建員工 ID 值類實(shí)例
val employeeId = EmployeeId("E12345")
// 創(chuàng)建員工對(duì)象并傳入員工 ID 值類實(shí)例
val employee = Employee("John Doe", employeeId)
println("Employee name: ${employee.name}, Employee ID: ${employee.employeeId.id}")
}
17.抽象類
抽象方法沒有實(shí)現(xiàn)體,只有方法簽名。子類必須實(shí)現(xiàn)抽象類中的所有抽象方法。非抽象方法,若想要在子類中重寫,必須使用open。抽象類可以包含具體方法和屬性,這些方法和屬性可以被子類繼承和使用。創(chuàng)建一個(gè) 匿名內(nèi)部類的實(shí)例 來實(shí)現(xiàn) 抽象類。
// 抽象類 Animal
abstract class Animal {
// 抽象方法
abstract fun makeSound()
val someProperty: Int = 10
// 非抽象方法,若想要在子類中重寫,必須使用open
open fun someMethod() {
println("This is a method in the abstract class.")
}
}
// 子類Dog ,繼承抽象類Animal
class Dog : Animal() {
override fun makeSound() {
println("Woof!")
}
override fun someMethod(){
println("dog someMethod")
}
}
// 調(diào)用
fun main() {
val dog = Dog()
dog.makeSound()
dog.someMethod()
// 創(chuàng)建一個(gè)匿名內(nèi)部類的實(shí)例來實(shí)現(xiàn)抽象類
var cat = object : Animal(){
override fun makeSound() {
println("Meow!")
}
}
cat.makeSound()
}
18.標(biāo)準(zhǔn)函數(shù)
1. run { … }
可以包含任意的表達(dá)式和語句。最后一個(gè)表達(dá)式的值 將作為 run的返回值。
// ‘data’ 修飾 類 ,會(huì)為這個(gè)類自動(dòng)生成一些實(shí)用的函數(shù)和特性
data class Person(val name: String, val age: Int)
val person = Person("Alice", 30).run {
// Person 類如果沒有data的修飾,這里打印的信息不易讀。
// 不易讀 ——> Created person: FileKt$main$Person@3941a79c
// 易讀 ——> Created person: Person(name=Alice, age=30)
println("Created person: $this")
this
}
2. let { … }
安全地調(diào)用可能為 null 的對(duì)象。 (如果一個(gè)變量可能為 null,使用 let 函數(shù)可以在確保變量不為 null 的情況下執(zhí)行一段代碼塊。)執(zhí)行特定操作,并返回一個(gè)值。臨時(shí)變量和代碼組織。 (使代碼更易于理解和維護(hù))
// 1. 安全調(diào)用
val str: String? = "123"
str?.let {
println(it.length)
}
// 2.鏈?zhǔn)秸{(diào)用
val str = "hello world".let {
println(it)
it.toUpperCase()
}.let {
println(it)
it.length
}
println(str)
// 3. 增強(qiáng)代碼可讀性
data class Person(val name: String, val age: Int)
val person = Person("Alice", 30)
val formattedInfo = person.let { p ->
val nameLength = p.name.length
val ageString = p.age.toString()
"Name length: $nameLength, Age: $ageString"
}
println(formattedInfo)
3. with { … }
簡(jiǎn)化對(duì)象屬性和方法的訪問。 (在一個(gè)代碼塊中提供對(duì)該‘對(duì)象的屬性和方法的直接訪問’)臨時(shí)對(duì)象的操作。
// 1.提高代碼的可讀性和簡(jiǎn)潔性
data class Person(val name: String, val age: Int)
val person = Person("Alice", 30)
with(person) {
// 無需每次都寫成person.name和person.age
println("Name: $name, Age: $age")
}
// 2.用完即丟棄
with(StringBuilder()) {
append("Hello")
append(" World")
println(this.toString())
}
4. apply { … }
特別適用于對(duì)象的初始化過程。在一個(gè)代碼塊中對(duì)對(duì)象進(jìn)行一系列的設(shè)置操作,最后返回被操作的'對(duì)象本身'(主動(dòng)返回的,不需要手動(dòng)設(shè)置)。
data class Rectangle(var width: Int, var height: Int)
val rectangle = Rectangle(10, 20).apply {
width = 15
}.apply {
height = 25
}
println(rectangle)
5. use { … }
資源管理的作用域函數(shù)。 在代碼塊執(zhí)行完畢后,自動(dòng)關(guān)閉所使用的資源。
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
try {
stream.use { inputStream ->
// 在這里使用輸入流進(jìn)行操作,如果發(fā)生異常,資源仍然會(huì)被正確關(guān)閉
}
} catch (e: IOException) {
// 處理異常
}
6. also { … } 接受一個(gè)對(duì)象作為參數(shù),并在一個(gè)代碼塊中允許對(duì)該對(duì)象執(zhí)行一些額外的操作,同時(shí)返回原始‘對(duì)象本身’。
data class Rectangle(val width: Int, val height: Int)
val rectangle = Rectangle(10, 20).also {
println("Rectangle: $it")
}.also {
// 這里可以執(zhí)行一些不改變對(duì)象的操作,比如記錄日志
}
柚子快報(bào)邀請(qǐng)碼778899分享:Kotlin基本語法
參考鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。