Android 之 Kotlin

變量

變量的聲明

Kotlin使用var,val來聲明變量,注意:Kotlin不再需要;來結尾

var?可變變量,對應java非final變量

var b = 1

val不可變變量,對應javafinal變量

val a = 1

兩種變量并未聲明類型,這是因為Kotlin存在類型推導機制,上述的a,b默認為Int。假設想聲明具體類型,則需下面的方式。

var c: Int = 1
基本類型

Kotlin不再存在基本類型,將全部使用對象類型

Java基本類型Kotlin對象類型對象類型說明
intInt整型
longLong長整型
shortShort短整型
floatFloat單精度浮點型
doubleDouble雙精度浮點型
booleanBoolean布爾型
charChar字符型
byteByte字節型

函數

函數的聲明

無參無返回值

fun test() {
}

有參有返回值

參數的類型需要寫在形參名后面中間使用:連接多個參數使用,分割",“返回值使用”:"拼接

fun add(a: Int, b: Int): Int {return a + b
}

聲明技巧

當函數體只有一行代碼時可直接使用下面方式聲明方法

fun add (a: Int, b: Int): Int = a + b 

Kotlin存在類型推導,返回值類型也可省略

fun add (a: Int, b: Int) = a + b
函數的調用
fun main() {test()println(add(1, 2))
}//運行結果
//test
//3

if語句

Kotlin中的選擇控制有兩種方式。ifwhen

if

Javaif區別不大,實現一個返回最大值的函數

fun max(a: Int, b: Int): Int {if (a > b) return aelse return b
}

Kotlin的if可以包含返回值,if語句的最后一行會作為返回值返回

fun max(a: Int, b: Int): Int {return if (a > b) a else b
}

上述我們說過一行代碼可省略返回值

fun max(a: Int, b: Int) = if (a > b) a else b

when語句

實現一個查詢成績的函數,用戶傳入名字,返回成績級別

if實現

Kotlinif語句必須要有else,不然會報錯

fun getScore(name: String) = if (name == "Tom") "不及格"
else if (name == "Jim") "及格"
else if (name == "Pony") "良好"
else if (name == "Tony") "優秀"
else "名字非法"

Kotlin==等價于Javaequals比較的時是對象里的內容,?===?等價于Java==,比較的為對象的引用。

when實現(相當于swich)

也必須實現else,否則報錯

fun getScore(name: String) = when(name) {"Tom" -> "不及格""Jim" -> "及格""Pony" -> "良好""Tony" -> "優秀"else -> "名字非法"
}

循環語句

Kotlin有兩種循環方式,whilefor-inwhilejava中的while沒有區別,for-in是對Java for-each的加強,Kotlin舍棄了for-i的寫法

while不再贅述,在學習for-in之前需要明確一個概念-區間

val range = 0..10 //區間代表[0,10]

for-in需借助區間來使用

fun main() {val range = 0..10for (i in range) { //也可直接for (i in 0..10)println(i)}//輸出結果為 從0打印到10
}

0..10?代表雙閉區間,如果想使用左閉右開呢,需要借助until關鍵字

fun main() {for (i in 0 until 10) {println(i)}//輸出結果為 從0打印到9
}

上述實現是逐步進行相當于i++Kotlin支持跳步

fun main() {for (i in  0 until 10 step 2) {println(i)}//輸出結果為0,2,4,6,8
}

for-in不僅可對區間進行遍歷,還可對集合進行遍歷,后續在集合處進行展示。

類和對象

類的創建和對象的初始化

創建Person類,并聲明nameage,創建printInfo方法

class Person {var name = ""var age = 0fun printInfo() {println(name +"'s age is " + age)}
}

main方法中聲明一個Person對象并調用printInfo方法

fun main() {val person = Person()person.name = "zjm"person.age = 20person.printInfo()
}
//結果如下zjm's age is 20
繼承

聲明Student類繼承PersonKotlin中繼承使用**:**,后接父類的構造,為什么需要構造后續講解

class Student : Person(){ //此時Person報錯var number = ""var grade = 0fun study() {println(name + "is studying")}
}

Person類為final不可被繼承,因此需借助open關鍵字

只需在Person類前加上open

open class Person {...
}
構造

構造分為主構造和此構造

主構造

主構造直接寫在類后面

修改Student

class Student(val number: String, val grade: Int) : Person(){...
}

因之前Person還有nameage,下面修改Person類的主構造

open class Person(val name: String, val age: Int) {...
}

此時Student報錯,因為繼承Person時,后邊使用的是Person()無參構造,上面我們修改了Person的構造,則不存在無參構造了。

再修改Student

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){...
}

此時不在報錯,聲明方式如下

val student = Student("zjm", 20, "1234", 90)

在構造時需要進行特殊處理怎么辦,Kotlin提供了init結構體,主構造的邏輯可在init中處理

open class Person(val name: String, val age: Int) {init {println("name is" + name)println("age is" + age)}
}

上述修改都為主構造,那如果類想有多個構造怎么辦,此時需借助次構造

次構造

此時實現Student的另外兩個構造

三個參數的構造,nameagenumbergrade不傳參默認為``0

無參構造,字符串默認為"",int默認為0

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {}constructor() : this("", 0, "", 0) {}...
}

創建如下:

fun main() {val student1 = Student("zjm", 20, "123", 90)val student2 = Student("zjm", 20, "123")val student3 = Student()
}
無主構造

若類不使用主構造,則后續繼承類也不需要使用構造即可去掉繼承類的(),次構造可以調用父類構造super進行初始化,但是次構造的參數在其他地方無法引用

class Student : Person {constructor(name: String, age: Int, number: String) : super(name, age) {}fun study() {//name,age可使用println(name + "is studying")//使用number則會報錯,若number是主構造的參數則可引用//println(number) 報紅}
}

接口

接口的定義

Java中的接口定義類似

interface Study {fun study()fun readBooks()fun doHomework()
}
接口的繼承

繼承接口只需在后用","拼接,需實現Study聲明的全部函數

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age), Study{...override fun study() {TODO("Not yet implemented")}override fun readBooks() {TODO("Not yet implemented")}override fun doHomework() {TODO("Not yet implemented")}
}

Kotlin支持接口方法的默認實現,JDK1.8以后也支持此功能,方法有默認實現則繼承類無需必須實現此方法

interface Study {fun study() {println("study")}fun readBooks()fun doHomework()
}

權限修飾符

JavaKotlin的不同如下表所示:

修飾符JavaKotlin
public所有類可見所有類可見(默認)
private當前類可見當前類可見
protected當前類,子類,同包下類可見當前類,子類可見
default同包下類可見(默認)
internal同模塊下的類可見

Kotlin引入internal,摒棄了default

使用:

類上

public open class Person(val name: String, val age: Int){...}

?變量上

private val value = 1

方法上

private fun test() {}

數據類和單例類

數據類

數據類則只處理數據相關,與Java Bean類似,通常需要實現其getsethashCodeequalstoString等方法

下面實現UserBean,包含idnamepwd屬性

Java編寫入如下:

public class UserBean {private String id;private String name;private String pwd;public UserBean() {}public UserBean(String id, String name, String pwd) {this.id = id;this.name = name;this.pwd = pwd;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;UserBean userBean = (UserBean) o;return Objects.equals(id, userBean.id) && Objects.equals(name, userBean.name) && Objects.equals(pwd, userBean.pwd);}@Overridepublic int hashCode() {return Objects.hash(id, name, pwd);}@Overridepublic String toString() {return "UserBean{" +"id='" + id + '\'' +", name='" + name + '\'' +", pwd='" + pwd + '\'' +'}';}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}
}

Kotlin編寫此類將變得非常簡單

一行代碼即可搞定,Kotlin會自動實現上述方法。

data class UserBean(val id: String, val name: String, val pwd: String)

若無data關鍵字,上述方法hashCodeequalstoString無法正常運行,去掉data查看Kotlin對應的java文件:

public final class UserBean {@NotNullprivate final String id;@NotNullprivate final String name;@NotNullprivate final String pwd;@NotNullpublic final String getId() {return this.id;}@NotNullpublic final String getName() {return this.name;}@NotNullpublic final String getPwd() {return this.pwd;}public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {Intrinsics.checkNotNullParameter(id, "id");Intrinsics.checkNotNullParameter(name, "name");Intrinsics.checkNotNullParameter(pwd, "pwd");super();this.id = id;this.name = name;this.pwd = pwd;}
}

發現上面代碼既無hashCodeequalstoString也無set

加上data且把變量改為var,對應的java文件如下:

public final class UserBean {@NotNullprivate String id;@NotNullprivate String name;@NotNullprivate String pwd;@NotNullpublic final String getId() {return this.id;}public final void setId(@NotNull String var1) {Intrinsics.checkNotNullParameter(var1, "<set-?>");this.id = var1;}@NotNullpublic final String getName() {return this.name;}public final void setName(@NotNull String var1) {Intrinsics.checkNotNullParameter(var1, "<set-?>");this.name = var1;}@NotNullpublic final String getPwd() {return this.pwd;}public final void setPwd(@NotNull String var1) {Intrinsics.checkNotNullParameter(var1, "<set-?>");this.pwd = var1;}public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {Intrinsics.checkNotNullParameter(id, "id");Intrinsics.checkNotNullParameter(name, "name");Intrinsics.checkNotNullParameter(pwd, "pwd");super();this.id = id;this.name = name;this.pwd = pwd;}@NotNullpublic final String component1() {return this.id;}@NotNullpublic final String component2() {return this.name;}@NotNullpublic final String component3() {return this.pwd;}@NotNullpublic final UserBean copy(@NotNull String id, @NotNull String name, @NotNull String pwd) {Intrinsics.checkNotNullParameter(id, "id");Intrinsics.checkNotNullParameter(name, "name");Intrinsics.checkNotNullParameter(pwd, "pwd");return new UserBean(id, name, pwd);}// $FF: synthetic methodpublic static UserBean copy$default(UserBean var0, String var1, String var2, String var3, int var4, Object var5) {if ((var4 & 1) != 0) {var1 = var0.id;}if ((var4 & 2) != 0) {var2 = var0.name;}if ((var4 & 4) != 0) {var3 = var0.pwd;}return var0.copy(var1, var2, var3);}@NotNullpublic String toString() {return "UserBean(id=" + this.id + ", name=" + this.name + ", pwd=" + this.pwd + ")";}public int hashCode() {String var10000 = this.id;int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;String var10001 = this.name;var1 = (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31;var10001 = this.pwd;return var1 + (var10001 != null ? var10001.hashCode() : 0);}public boolean equals(@Nullable Object var1) {if (this != var1) {if (var1 instanceof UserBean) {UserBean var2 = (UserBean)var1;if (Intrinsics.areEqual(this.id, var2.id) && Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.pwd, var2.pwd)) {return true;}}return false;} else {return true;}}
}

此時則和手動編寫的java bean功能一樣了,所有方法都可正常運行

單例類

目前Java使用最廣的單例模式的實現如下:

public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}public void test() {...}
}

Kotlin中創建單例類需選擇Object

生成代碼如下

object Singleton {fun test() {...}
}

其對應的java文件如下,和上述使用最多的java單例實現類似

public final class Singleton {@NotNullpublic static final Singleton INSTANCE;public final void test() {}private Singleton() {}static {Singleton var0 = new Singleton();INSTANCE = var0;}
}

?使用如下:

fun main() {Singleton.test() //對應的java代碼為Singleton.INSTANCE.test();
}

許多高級語言都支持Lambdajavajdk1.8以后才支持Lamda語法,LamdaKotlin的靈魂所在,此小節對Lambda的基礎進行學習,并借助集合練習。

集合的創建和遍歷

List
fun main() {//常規創建val list = ArrayList<Int>()list.add(1)list.add(2)list.add(3)//listOf不可變,后續不可添加刪除,只能查val list1 = listOf<Int>(1, 2, 3 ,4 ,5)list1.add(6)//報錯//mutableListOf,后續可添加刪除val list2 = mutableListOf<Int>(1, 2, 3 ,4 ,5)list2.add(6)//循環for (value in list2) {println(value)}
}
Set

set用法與List類似,只是把listOf替換為mapOf

Map

fun main() {val map = HashMap<String, String>()map.put("1", "zjm")map.put("2", "ljn")//Kotlin中map支持類似下標的賦值和訪問map["3"] = "lsb"map["4"] = "lyx"println(map["2"])println(map.get("1"))//不可變val map1 = mapOf<String, String>("1" to "zjm", "2" to "ljn")map1["3"] = "lsb" //報錯//可變val map2 = mutableMapOf<String, String>("1" to "zjm", "2" to "ljn")map2["3"] = "lsb"for ((key, value) in map) {println(key + "   " + value)}}

Lambda

Lambda的使用
方法在傳遞參數時都是普通變量,而Lambda可以傳遞一段代碼

Lambda表達式的語法結構

{參數名1: 參數類型, 參數名2:參數類型 -> 函數體}

Kotlin的list提供了maxByOrNull函數,返回當前list中xx最大的元素,XX是我們定義的條件,可能為長度,可能是別的,我們拿長度舉例。

若不使用maxBy,實現如下

fun main() {val list = listOf<String>("a", "aba", "aabb", "a")var maxStr = ""for (str in list) {if (str.length > maxStr.length) {maxStr = str;}}println(maxStr)
}

maxByOrNull是一個普通方法,需要一個Lambda參數,下面結合Lambda使用maxByOrNull

fun main() {val list = listOf<String>("a", "aba", "aabb", "a")var lambda = {str: String -> str.length}var maxStr = list.maxByOrNull(lambda)println(maxStr)
}

直接當成參數也可傳遞

var maxStr = list.maxByOrNull({str: String -> str.length})

Lambda為方法的最后一個參數,則可將{}提到外面

var maxStr = list.maxByOrNull() {str: String -> str.length}

若有且僅有一個參數且是Lambda,則可去掉()

var maxStr = list.maxByOrNull {str: String -> str.length}

Kotlin擁有出色的類型推導機制,Lambda參數過多時可省略參數類型

var maxStr = list.maxByOrNull {str -> str.length}

Lambda只有一個參數,則可用it替代參數名

var maxStr = list.maxByOrNull {it.length}

集合還有許多此類函數

創建list,后續操作都由此list轉換

val list = listOf<String>("a", "aba", "aabb", "a")

map?映射,返回新集合,將集合中的元素映射成另一個值

val newList = list.map { it.toUpperCase() }//將集合中的元素都準換成大寫

filter過濾,返回新集合,將集合中的元素進行篩選

val newList = list.filter { it.length > 3 }//篩選出長度大于3的元素

any返回Boolean,集合中是否存在元素滿足Lambda的條件,有則返回true,無則false

val isAny = list.any {it.length > 10} //返回false

all返回Boolean,集合中元素是否全部滿足滿足Lambda的條件,有則返回true,無則false

val isAll = list.all {it.length > 0} //返回true

Lambda的簡單使用到這就結束了

Java函數式API的使用

Kotlin調用Java方法,若該方法接收一個Java單抽象方法接口參數,則可使用函數式APIJava單抽象方法接口指的是接口只聲明一個方法,若有多個方法則無法使用函數式API

Java單抽象方法接口例如Runnable

public interface Runnable {void run();
}

Java中啟動一個線程如下:

new Thread(new Runnable() {@Overridepublic void run() {System.out.println("test");}
}).start();

Kotlin啟動線程如下:

Kotlin摒棄了new,若想聲明匿名內部類必須使用object

Thread(object : Runnable {override fun run() {println("test")}
}).start()

RunnableJava單抽象方法接口,可對代碼進行簡化

Thread(Runnable {println("test")}).start()

Runnable接口只用一個方法,使用Lambda也不會有歧義,Kotlin知道此Lambda一定實現的為run函數,借用Lambda進一步簡化:

Thread({println("test")
}).start()

又因Thread只需一個參數Runnable參數,則可省略()

Thread {println("test")
}.start()

與上類似的,click也使用上述方法

button.setOnClickListener { println("test") }

這種方式可極大縮減代碼量

空指針檢查機制

國外統計程序出現最多的異常為空指針異常,Kotlin存在編譯時檢查系統幫助我們發現空指針異常。

查看下面Java代碼

public void doStudy(Study study) {study.doHomework();study.readBooks();
}

上述代碼時存在空指針風險的,傳入null,則程序崩潰,對其進行改進

public void doStudy(Study study) {if (study != null) {study.doHomework();study.readBooks();}
}

對于Kotlin來講任何參數和變量不能為空

fun study(study: Study) {study.doHomework()study.readBooks()
}fun main() {study(null) //報錯study(Student()) //正確
}

Kotlin把空指針異常的檢查提前到了編譯期,若空指針則編譯期就會崩潰,避免在運行期出現問題

若我們有特殊的需求可能需要傳遞null參數,參數則按照下面聲明

fun study(study: Study?) {study.doHomework() //報錯study.readBooks()	//報錯
}

?的意思則是當前參數可為空,如果可為空的話,則此對象調用的方法必須要保證對象不為空,上面代碼沒有保證,則報錯,修改如下

fun study(study: Study?) {if (study != null) {study.doHomework()study.readBooks()}
}

也可借助判空輔助工具

判空輔助工具
?.

其含義是前面對象不為空才執行.后面的方法

fun study(study: Study?) {study?.doHomework()study?.readBooks()
}
?:

其含義是前不為空則返回問號前的值,為空則返回后的值

比如

val c = if (a !=null ) {a
} else {b
}

借助?:則可簡化為

val c = a ?: b

再比如

fun getTextLength(text: String?): Int {if (text != null) {return text.length}return 0
}

借助?:?則可簡化為

fun getTextLength(text: String?) = text?.length ?: 0
!!

有些時候我們想要強行通過編譯,就需要依靠!!,這時就是程序員來保證安全

fun study(study: Study?) {//假設此時為空拋出異常,則和java一樣study!!.doHomework()study!!.readBooks()
}

let函數

let不是關鍵字,而是一個函數,提供了函數式API的編程接口,會將調用者作為參數傳遞到Lambda表達式,調用之后會立馬執行Lambda表達式的邏輯

obj.let { it -> //it就是obj//編寫操作
}

比如上面函數

fun study(study: Study?) {study.doHomework()  //報錯study.readBooks()	//報錯
}

借助let則可改為

fun study(study: Study?) {//此時靠?.則保證了study肯定不為空,才會執行let函數study?.let {//it為studyit.doHomework()it.readBooks()}
}

全局判空注意事項

//全局變量
var study: Study? = null
fun study() {//報錯if (study != null) {study.readBooks()study.doHomework()}
}

因全局變量隨時有可能被其他線程修改,即使判空處理也不能保證其沒有空指針風險,而let則可規避上述問題

var study: Study? = null
fun study() {study?.let {it.doHomework()it.readBooks()}
}

內嵌表達式?$

之前我們拼接字符串都是下面這樣

var name = "zjm"
var age = 20
println("My name is " + name + ". I am " + age + ".")
//打印結果
//My name is zjm. I am 20.

現在靠著Kotlin提供的內嵌表達式則不需要拼接,只需要下面這樣則可實現

var name = "zjm"
var age = 20
println("My name is $name. I am $age." )
//打印結果
//My name is zjm. I am 20.
內嵌表達式復雜操作

${程序員想要的操作}

var name = "zjm"
var age = 20
println("My name is ${if (1 < 2) "zjm" else "ljn"}. I am $age." )
//打印結果
//My name is zjm. I am 20.

函數的參數默認值

Kotlin支持函數存在默認值,使用如下

fun main() {myPrint(1)myPrint(1, "lalala")
}fun myPrint(value: Int, str: String = "hello") {println("num is $value, str is $str")
}//結果如下
//num is 1, str is hello
//num is 1, str is lalala

value想為默認值,則會報錯,因為在使用時傳入的第一個參數他認為是int的,傳入字符串會類型不匹配

fun main() {myPrint("zjm")//報錯
}fun myPrint(value: Int = 100, str: String) {println("num is $value, str is $str")
}

Kotlin提供了一種鍵值對傳參來解決上述問題

fun main() {myPrint(str = "zjm") //正確調用
}fun myPrint(value: Int = 100, str: String) {println("num is $value, str is $str")
}

回顧之前的主次構造,Student如下

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {}...
}

上述的此構造借助參數默認值技巧是可以不寫的,將第四個參數默認值為0 即可

class Student(name: String,  age: Int, val number: String, val grade: Int = 0) : Person(name, age){...
}

by lazy

Kotlin 的?by lazy?是一種??延遲初始化屬性??的委托機制,主要用于優化資源加載、減少啟動開銷,并簡化代碼邏輯

1. ??基本特性與工作原理??
  • ??延遲初始化??:by lazy?定義的屬性僅在首次訪問時執行初始化邏輯,后續訪問直接返回緩存值。
  • ??只讀屬性??:僅適用于?val(不可變變量),初始化后值不可修改。
  • ??線程安全??:默認使用?LazyThreadSafetyMode.SYNCHRONIZED?模式,通過雙重檢查鎖(double-checked locking)確保多線程安全
// 默認線程安全模式
val database: Database by lazy {Database.connect("jdbc:mysql://localhost:3306/mydb")
}
???Android 中的典型應用場景??
  • ??ViewModel 初始化??:推遲創建直到首次訪問,避免?Activity/Fragment?構造時的額外開銷
class MainActivity : AppCompatActivity() {private val viewModel by lazy { ViewModelProvider(this).get(MainViewModel::class.java) }
}
  • 高開銷資源??:如數據庫連接、文件讀取或網絡客戶端。
  • ??按需加載視圖??:僅在需要時初始化復雜 UI 組件(如自定義控件)。

lateinit

Kotlin 的?lateinit?是一種??延遲初始化非空可變屬性??的機制,主要用于解決對象在聲明時無法立即賦值但后續保證會被初始化的問題

可變屬性??

  • 僅適用于?var?變量,不可用于?val(常量)。
  • ??非空類型限制??:只能用于對象類型(如?StringView),??不支持原始數據類型??(如?IntBoolean

Android 中的典型應用場景??

  1. ??視圖綁定與控件初始化??

    • 在?Activity/Fragment?的?onCreate()?中初始化?View,避免聲明時立即加載資源
class MainActivity : AppCompatActivity() {lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater) // 手動初始化setContentView(binding.root)}
}

2.ViewModel 屬性賦值??

  • 在?ViewModel?中聲明非空屬性,并在?Activity?中通過?ViewModelProvider?賦值
class MyViewModel : ViewModel() {lateinit var userData: String // 稍后由 Activity 賦值
}

by lazy與?lateinit?的對比??

by lazy?和?lateinit?均用于延遲初始化,但適用場景不同:

??特性????by lazy????lateinit??
??適用變量類型??val(只讀)var(可變)
??初始化時機??首次訪問時自動初始化需手動顯式初始化
??線程安全??默認支持(可配置模式)無內置線程安全
??支持數據類型??所有類型(含基本類型)僅非空對象類型(不含?Int?等)
??典型場景??單例、高開銷資源、只讀配置Android 視圖綁定、依賴注入

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92030.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92030.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92030.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Design Compiler:布圖規劃探索(ICC)

相關閱讀 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 簡介 在Design Compiler Graphical中&#xff0c;可以用布圖規劃探索(Floorplan Exploration)功能&#xff0c;打開IC Compiler進行布圖規劃的創建、修改與分…

《藍牙低功耗音頻技術架構解析》

《2025GAS聲學大講堂—音頻產業創新技術公益講座》低功耗藍牙音頻系列專題LE Audio & Auracast?專題講座第1講將于8月7日周四19點開講&#xff0c;本次邀請了藍牙技術聯盟 技術與市場經理 魯公羽 演講&#xff0c;講座主題&#xff1a;《藍牙低功耗音頻技術架構解析》。&…

ubuntu apt安裝與dpkg安裝相互之間的關系

0. 問題解釋 在linux系統中&#xff0c;使用neofetch命令可以看到現在系統中使用dpkg, flatpak, snap安裝的包的數量&#xff0c;那么使用apt安裝的包被統計在什么位置了呢&#xff0c;使用apt的安裝流程和使用flatpak的安裝流程有什么關系和區別呢?1. apt 安裝的包在哪里&…

YooAsset源碼閱讀-Downloader篇

YooAsset源碼閱讀-Downloader 繼續 YooAsset 的 Downloader &#xff0c;本文將詳細介紹如何創建下載器相關代碼 CreateResourceDownloaderByAll 關鍵類 PlayModeImpl.csResourceDownloaderOperation.csDownloaderOperation.csBundleInfo.cs CreateResourceDownloaderByAll 方法…

豆包新模型與 PromptPilot 實操體驗測評,AI 輔助創作的新范式探索

摘要&#xff1a;在 AI 技術飛速發展的當下&#xff0c;各類大模型及輔助工具層出不窮&#xff0c;為開發者和創作者帶來了全新的體驗。2025 年 7 月 30 日廈門站的火山方舟線下 Meetup&#xff0c;為我們提供了近距離接觸豆包新模型與 PromptPilot 的機會。本次重點體驗了實驗…

深入探討AI在測試領域的三大核心應用:自動化測試框架、智能缺陷檢測和A/B測試優化,并通過代碼示例、流程圖和圖表詳細解析其實現原理和應用場景。

引言隨著人工智能技術的飛速發展&#xff0c;軟件測試領域正在經歷一場深刻的變革。AI技術不僅提高了測試效率&#xff0c;還增強了測試的準確性和覆蓋范圍。本文將深入探討AI在測試領域的三大核心應用&#xff1a;自動化測試框架、智能缺陷檢測和A/B測試優化&#xff0c;并通過…

音視頻學習筆記

0.vs應用其他庫配置1基礎 1.1視頻基礎 音視頻錄制原理音視頻播放原理圖像表示rgb圖像表示yuvhttps://blog.51cto.com/u_7335580/2059670 https://blog.51cto.com/cto521/1944224 https://blog.csdn.net/mandagod/article/details/78605586?locationNum7&fps1 視頻主要概念…

LLM隱藏層狀態: outputs.hidden_states 是 MLP Residual 還是 Layer Norm

outputs.hidden_states 是 MLP Residual 還是 Layer Norm outputs.hidden_states 既不是單純的 MLP Residual,也不是單純的 Layer Norm,而是每一層所有組件(包括 Layer Norm、注意力、MLP、殘差連接等)處理后的最終隱藏狀態。具體需結合 Transformer 層的結構理解: 1. T…

XML 用途

XML 用途 引言 XML&#xff08;可擴展標記語言&#xff09;是一種用于存儲和傳輸數據的標記語言。自1998年推出以來&#xff0c;XML因其靈活性和可擴展性&#xff0c;在眾多領域得到了廣泛應用。本文將詳細介紹XML的用途&#xff0c;幫助讀者全面了解這一重要技術。 一、數據存…

亞馬遜撤離Google購物廣告:重構流量生態的戰略博弈

戰略突變&#xff1a;從漸進收縮到全面退潮的背后邏輯亞馬遜在2025年7月突然全面停止Google Shopping廣告投放&#xff0c;這場看似 abrupt 的決策實則經歷了一年多的戰略鋪墊&#xff0c;從2024年Q1開始的預算削減&#xff0c;到2025年Q2美國市場支出減半&#xff0c;直至核心…

【QT】常?控件詳解(三)常用按鈕控件PushButton RadioButton CheckButton Tool Button

文章目錄前言一、PushButton1.1 QAbstractButton1.2 添加圖標的按鈕1.3 給按鈕添加快捷鍵1.4 代碼?例:按鈕的重復觸發二、 RadioButtion2.1簡介2.2 幾個槽函數 click,press,release, toggled 的區別2.2 模擬分組點餐三、 CheckBox四、Tool Button&#x1f6a9;總結前言 一、P…

數據結構:反轉鏈表(reverse the linked list)

目錄 通過交換元素值實現反轉&#xff08;reverse by swapping elements&#xff09; 滑動指針&#xff08;sliding pointers&#xff09; 使用滑動指針反轉鏈表&#xff08;Reversing a Linked List using Sliding Pointers&#xff09; 對比分析 如何用遞歸&#xff08;R…

【C#】基于SharpCompress實現壓縮包解壓功能

1.SharpCompress安裝 在vs的nuget下搜索安裝SharpCompress&#xff0c;如圖所示2.解壓縮包功能實現 /// <summary> /// 解壓壓縮包 /// </summary> /// <param name"filePath">壓縮包文件路徑</param> /// <param name"directoryPat…

mybatis連接PGSQL中對于json和jsonb的處理方法

pgsql數據庫表字段設置了jsonb格式&#xff1b;在java的實體里使用String或者對象轉換會一直提示一個錯誤&#xff1a; Caused by: org.postgresql.util.PSQLException: ERROR: column “xx” is of type jsonb but expression is of type character varying 需要加一個轉換方法…

Spring AI Alibaba Graph 深度解析:原理、架構與應用實踐

1. 引言概述 1.1 什么是 Spring AI Alibaba Graph Spring AI Alibaba Graph 是阿里云團隊基于 Spring AI 生態開發的一個強大的工作流編排框架&#xff0c;專門用于構建復雜的 AI 應用。它采用聲明式編程模型&#xff0c;通過圖結構來定義和管理 AI 工作流&#xff0c;讓開發…

C++少兒編程(二十一)—軟件執行流程

讓我們將以下程序視為用C編寫的示例程序。步驟1&#xff1a;預處理器將源代碼轉換為擴展代碼。當您運行程序時&#xff0c;源代碼首先被發送到稱為預處理器的工具。預處理器主要做兩件事&#xff1a;它會從程序中刪除注釋。它擴展了預處理器指令&#xff0c;如宏或文件包含。它…

精通Webpack搭建Vue2.0項目腳手架指南

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;在Web應用程序開發中&#xff0c;Vue 2.0因其虛擬DOM、單文件組件、增強的生命周期鉤子和Vuex及Vue Router狀態管理與路由解決方案&#xff0c;成為了提高開發效率和代碼組織性的關鍵。Webpack作為必不可少的模…

無償分享120套開源數據可視化大屏H5模板

數據可視化跨越了語言、技術和專業的邊界&#xff0c;是能夠推動實現跨界溝通&#xff0c;實現國際間跨行業的創新的工具。正如畫家用顏料表達自我&#xff0c;作者用文字講述故事&#xff0c;而統計人員用數字溝通 ...... 同樣&#xff0c;數據可視化的核心還是傳達信息。而設…

Qt按鍵響應

信號與槽機制是一個非常強大的事件通信機制&#xff0c;是 Qt 最核心的機制之一&#xff0c;初學者掌握它之后&#xff0c;幾乎可以做任何交互操作。信號&#xff08;Signal&#xff09; 是一種“事件”或“通知”&#xff0c;比如按鈕被點擊、文本改變、窗口關閉等。 槽&#…

【Git】常見命令整理

Git分區與操作關系&#xff1a;Working Directory&#xff08;工作區&#xff0c;對于本地的編輯和修改在此進行&#xff09;->Staging Area&#xff08;暫存區/Index&#xff0c;在工作區進行git add操作后的位置&#xff09;->Git Repository&#xff08;本地倉庫&…