【Golang筆記02】函數、方法、泛型、接口學習筆記

Golang筆記02:函數、方法、泛型、接口學習筆記

一、進階學習

1.1、函數

go中的函數使用func關鍵字進行定義,go程序的入口函數叫做:main,并且必須是屬于main包里面。

1.1.1、定義函數
(1)普通函數

go中定義函數,需要使用func關鍵字,同時要指定函數名稱,函數參數,函數返回值,函數體,這就是函數的五要素。語法格式:

func 函數名稱(參數1,參數2,...)(返回值類型1,返回值類型2,...) {// 函數體
}// 當只有一個返回值類型的時候,可以省略括號(),直接寫類型即可

go語言中,函數允許返回多個返回值,這個語法和其他的一些編程語言是有些區別的,比如:Java語言中,只允許一個函數返回一個返回值。go語言中,函數的特點:

  • 允許返回多個返回值。
  • 不允許函數重載。
// Method01 定義函數
func Method01() int {return 1 + 2
}// Method02 定義函數
func Method02(a int, b int) (int,int) {return a + b, a - b;
}

另外,如果函數參數的類型都是一致的,那么可以簡寫成下面這種方式:

// Method02 定義函數,參數類型相同,則可以簡寫
func Method02(a, b int) (int,int) {return a + b, a - b;
}
(2)函數字面量

函數字面量,是指將函數作為一個變量先定義出來,接著在需要使用的時候,通過func重新定義一個函數,然后函數字面量指向func函數。如下所示:

package mainimport "fmt"// 先定義一個函數字面量,函數體不定義
var method func(int, int) (int, int)// Method02 定義函數
func Method02(a int, b int) (int, int) {return a + b, a - b
}func main() {// 這里給函數字面量,指向具體的函數實現method := func(a int, b int) (int, int) {return a + b, a - b}// 調用函數add, sub := method(1, 2)fmt.Println(add, sub)
}
1.1.2、函數參數和返回值
(1)函數參數

go語言中的函數參數,如果是相同數據類型的,則可以統一定義類型,不需要每個參數都寫出類型名稱。格式:

func 函數名稱(參數1,參數2,參數3 數據類型)(返回值1,返回值2...) {// 函數體
}

另外,go中函數參數的傳遞是值傳遞,也就是說,函數參數傳遞的時候,會拷貝實參的值。在函數體內修改函數參數的值,不會影響實參的值。

如果要定義可變參數,那么可以使用【...】符號,并且可變參數只能夠在最后一個參數位置出現。

// 可變參數
func Method03(args ...int) {}
(2)函數返回值

go語言中,函數的返回值允許定義多個,當只有一個返回值,則可以不寫括號,超過一個返回值的時候,則必須使用括號將所有返回值包裹起來。

// 只有一個返回值,可以省略返回值的括號
func demo() int {}
// 多返回值
func demo() (int,string){}

另外,go中函數返回值也可以定義名稱,定義返回值名稱之后,那么這個參數就可以在函數體中直接使用,并且通過return返回結果。

// Method02 定義函數
func Method02(a, b int) (add int,sub int) {// 可以使用函數返回值名稱add = a + bsub = a - b// 定義了返回值名稱,則return的時候,可以不寫// 等價于 return add, subreturn//return add, sub
}
1.1.3、匿名函數

匿名函數,顧名思義,就是沒有函數名稱的函數。匿名函數一般在函數內部使用,語法格式:

package mainimport "fmt"func main() {// 定義匿名函數,并且調用函數ans := func(a, b int) int {ans := a + breturn ans}(1, 2)fmt.Println(ans)
}

匿名函數也可以作為一個函數的參數,例如:

package mainimport "fmt"// 定義函數,并且函數接受一個函數作為參數
func demo(a, b int, call func(int, int) int) int {return call(a, b)
}func main() {// 調用函數ans := demo(1, 2, func(a, b int) int {return a * b})fmt.Println(ans)// 調用函數ans2 := demo(1, 2, func(a, b int) int {return a + b})fmt.Println(ans2)
}
1.1.4、閉包

go語言中,函數有一個閉包的概念,閉包在一些編程語言中,又叫做:Lamda表達式。閉包,可以在內部函數中訪問到外部函數的變量,即使外部函數已經執行完畢,內部函數仍然可以訪問到外部的變量,這個過程就叫做:閉包。

  • 閉包=匿名函數+外部環境變量引用

下面給一個閉包的案例:

package mainimport "fmt"func main() {// 創建一個匿名函數,并且返回值是一個函數類型sum := func() func() int {a, b := 1, 1// 返回一個匿名函數,相當于回調函數,并且還修改外部函數 a、b 兩個變量的值return func() int {// 引用外部函數的變量a, b = b, a+breturn a}}// 調用函數,并且返回值是個回調函數getSum := sum()for i := 0; i < 10; i++ {// 調用回調函數,由于閉包的特性,回調函數中仍然可以使用 sum() 函數中的變量 a、bfmt.Println(getSum())}
}

閉包結構中,外部函數執行結束之后,內部函數就相當于一個回調函數一樣,仍然可以被繼續調用,并且還可以使用外部函數中的變量。另外,多次調用外部函數獲取到的回調函數,是互不影響的。

package mainimport "fmt"func demo() func() int {count := 0return func() int {count++return count}
}func main() {// 第一次調用外部函數f1 := demo()fmt.Println("調用f1()函數")fmt.Println(f1())fmt.Println(f1())fmt.Println(f1())// 第二次調用外部函數f2 := demo()fmt.Println("調用f2()函數")fmt.Println(f2())fmt.Println(f2())fmt.Println(f2())fmt.Println("再次調用 f1() 函數")// 再次調用 f1() 函數fmt.Println(f1())
}

上面案例中,就是演示的多次調用外部函數,獲取到的回調函數之間是互不影響的。運行結果如下所示:

調用f1()函數
1
2
3
調用f2()函數
1
2
3
再次調用 f1() 函數
4

從上面的執行結果可以看到,f1()f2()之間的閉包結構是互不影響的。

1.1.5、延遲調用

go語言中,提供了一個defer關鍵字,可以用于聲明函數的延遲調用功能。defer聲明的延遲函數,會在外部函數執行完成之前,調用延遲函數,一般用于釋放文件資源,關閉連接等操作。

注意:當一個函數中,存在多個defer定義的延遲函數,那么go會根據后進先出的規則,依次調用延遲函數。

怎么理解執行完成之前,才會調用defer延遲函數呢???

  • 當聲明了defer函數的代碼塊內,執行到最后一行代碼語句,后面已經沒有可執行的語句的時候,但是函數還沒有結束執行,只有遇到函數的最后一個右花括號【}】,才算執行結束。
  • 那么defer函數,就是在遇到右花括號【}】之前,會被調用的。
package mainimport "fmt"func deferDemo() {fmt.Println("3、執行延遲函數...")
}func main() {fmt.Println("1、執行main函數代碼...")// 采用延遲函數的方式,調用方法,將在 main 函數執行完成之前,調用 deferDemo() 函數defer deferDemo()fmt.Println("2、執行main函數最后一句代碼...")
}// 控制臺輸入結果
1、執行main函數代碼...
2、執行main函數最后一句代碼...
3、執行延遲函數...

從上面案例代碼中,可以看到,雖然defer函數聲明在中間位置,但是從控制臺輸出的結果來看,defer函數的內容確是最后打印出來的,這也就說明defer函數是最后執行的。

注意了,當存在多個defer延遲函數的時候,Go語言會按照后進先出的順序,依次執行defer延遲函數。案例代碼:

package mainimport "fmt"func demo01() {fmt.Println("調用demo01()函數...")
}
func demo02() {fmt.Println("調用demo02()函數...")
}
func demo03() {fmt.Println("調用demo03()函數...")
}func main() {fmt.Println("開始執行main函數...")// 定義延遲函數defer demo02()defer demo01()defer demo03()fmt.Println("main函數執行完成...")
}// 執行結果
開始執行main函數...
main函數執行完成...
調用demo03()函數...
調用demo01()函數...
調用demo02()函數...

1.2、方法

go語言中,既有函數,又有方法,在其他的語言中,一般情況下,函數和方法都是同一個概念,但是在go語言里面,兩者是有點不同的。

go中的函數和方法,在定義形式上大體相同,只不過方法的定義,需要顯示的聲明方法的接收者,只有接收者才可以調用方法。方法定義格式:

// 自定義方法接收者的類型
type 接收者類型名稱 接收者實際數據類型func (方法接收者名稱 接收者類型名稱) 方法名稱(方法參數) 返回值類 {// 方法體
}

什么是方法接收者呢???要如何理解方法接收者這個概念???

  • 方法的接收者,可以理解成是方法的調用者,它是規定哪一種數據類型的對象,可以調用這個方法。
  • go語言中的方法接收者,就類似于java語言中的this關鍵字,例如:this.demo(),這個this就是方法的接收者,也可以理解成調用者。

方法的調用一般需要和自定義類型結合使用。

調用方法的語法格式:

變量名稱 := 值
變量名稱.方法名稱()

方法的調用和函數的調用有點區別,函數是直接在代碼中調用即可,不需要指定是由誰觸發的調用。而方法,則需要指定具體的調用對象,是由哪個變量對象觸發的方法調用。

package mainimport "fmt"// MyInt 先自定義一個類型
type MyInt intfunc (myInt MyInt) setValue(value int) {// 修改參數值myInt = MyInt(value)fmt.Println("方法中,修改的值=", myInt)
}func main() {var myInt MyInt = 1fmt.Println("修改之前的值=", myInt)// 調用方法myInt.setValue(2)fmt.Println("調用方法,修改之后的值=", myInt)
}// 執行結果
修改之前的值= 1
方法中,修改的值= 2
調用方法,修改之后的值= 1

從上面案例代碼中,可以看到,我們雖然調用了setValue()方法去修改myInt的變量,但是方法執行完成之后,myInt的值仍然沒有變化,這是為什么呢???

這就涉及到一個知識點了,方法的接收者分為兩種情況:值接收者指針接收者

1.2.1、值接收者

go中方法的值接收者,是指方法接收者是通過值傳遞到方法里面的,傳遞的是形參,修改形參是不會影響到實際參數的。這和Java中的值傳遞的概念相同。

要想在方法里面,修改接收者的數據,那就需要通過指針接收者來實現。

1.2.2、指針接收者

方法指針接收者,這和Java中的引用傳遞的概念相同,在一個方法中,對引用傳遞的參數進行修改,實際上是對這個引用地址指向的數據進行了修改,會影響實際的參數。

go中的指針接收者作用就和Java引用傳遞作用相同,通過指針接收者修改數據,會將實際參數的值也一起更新了。

package mainimport "fmt"// MyInt 先自定義一個類型
type MyInt int// 方法接收者采用指針類型
func (myInt *MyInt) setValue(value int) {// 修改參數值*myInt = MyInt(value)fmt.Println("方法中,修改的值=", *myInt)
}func main() {var myInt MyInt = 1fmt.Println("修改之前的值=", myInt)// 調用方法,雖然 myInt 這里是值類型,但是 Go 會將其編譯之后,就相當于是 (&myInt).setValue(2)myInt.setValue(2)fmt.Println("調用方法,修改之后的值=", myInt)
}// 執行結果
修改之前的值= 1
方法中,修改的值= 2
調用方法,修改之后的值= 2

1.3、接口介紹

Go中的接口分為兩大類:基本接口通用接口

  • 基本接口:接口內部是一組方法的集合。
  • 通用接口:接口內部是一組類型的集合。

接口,是一組規范的集合,也就是說,接口只會規定實現功能的規范,但是具體的功能邏輯是怎么實現的,接口不負責,具體的功能實現交給具體的實現類。

Go中沒有類與繼承的概念,而是通過結構體來實現類的功能,那么在接口實現上,也是通過結構體來實現的。你可以怎么理解,創建一個struct結構體,就相當于是Java中創建了一個Class類。

1.3.1、基本接口

Go中定義接口需要使用interface關鍵字,這個關鍵字用于標識是接口類型。

(1)定義接口

基本接口的語法格式,如下所示:

// 基本接口的定義
type 接口名稱 interface {// 定義方法方法名稱(參數類型) 返回值類型方法名稱(參數類型) 返回值類型方法名稱(參數類型) 返回值類型
}

在定義基本接口的時候,接口內部只能夠是一組方法的集合,不能存在其他的類型集合。針對接口中的方法,方法參數可以不用寫參數名稱,只需要指定類型即可,因為接口不具備實現邏輯,也就不會使用方法參數,所以寫不寫參數名稱都沒關系,但是類型是必須要規定的。

package mainimport "fmt"// BaseInterface 定義基本接口
type BaseInterface interface {// Say 定義兩個方法Say(string) stringWalk()
}func main() {// 初始化接口var baseInterface BaseInterfacefmt.Println(baseInterface)
}

上面代碼,就是定義了一個基本接口,并且在main函數中,初始化了接口,但是這個接口還沒有具體實現,只是初始化了。

(2)接口實現

接口定義好了之后,那么要如何實現這個接口中的方法呢???Go語言中沒有提供類似Java中的implements關鍵字,那么要怎么樣才能實現接口呢???

Go語言中,接口的實現方式很簡單,只需要一種類型(結構體或者自定義類型)將接口中的所有方法都實現了,那么我們就說,這個類型實現了某某接口。

package mainimport "fmt"// BaseInterface 定義基本接口
type BaseInterface interface {// Say 定義兩個方法Say(string) stringWalk()
}// CustomType 定義類型,實現接口
type CustomType struct{}// Say CustomType 實現 BaseInterface 接口的方法
func (customType CustomType) Say(s string) string {fmt.Println("CustomType實現接口:saying..." + s)return s
}// Walk CustomType 實現 BaseInterface 接口的方法
func (customType CustomType) Walk() {fmt.Println("CustomType實現接口:walking...")
}func main() {
}

上面案例代碼中,自定義了CustomType結構體類型,然后這個結構體定義了兩個方法,方法和接口中定義的方法名稱一致,那么這種情況下,CustomType類型就是實現了BaseInterface接口了。

Go語言中接口的實現都是隱式的,不像Java中的接口實現那樣,還需要使用implements關鍵字才能夠實現接口。

(3)使用接口

實現接口之后,就需要在相應的地方,使用接口實現來完成業務功能啦。使用接口很簡單,其實就是通過接口的實現類,調用對應的接口方法即可。

package mainimport "fmt"// BaseInterface 定義基本接口
type BaseInterface interface {// Say 定義兩個方法Say(string) stringWalk()
}// CustomType 定義類型,實現接口
type CustomType struct{}// Say CustomType 實現 BaseInterface 接口的方法
func (customType CustomType) Say(s string) string {fmt.Println("CustomType實現接口:saying..." + s)return s
}// Walk CustomType 實現 BaseInterface 接口的方法
func (customType CustomType) Walk() {fmt.Println("CustomType實現接口:walking...")
}func main() {// 定義接口實現類customType := CustomType{}// 調用接口方法say := customType.Say("Hello World")fmt.Println("返回值:" + say)customType.Walk()
}

從上面案例代碼中,可以發現一個問題,在使用接口的時候,我們的代碼里面沒有直接出現BaseInterface這個接口,而是定義了一個CustomType結構體的變量,然后通過結構體變量去調用了結構體實現的SayWalk兩個方法。

這是因為Go語言中,某個類型(結構體或者自定義類型)實現某個接口之后,對應的類型就已經滿足接口中定義的方法規范。

(4)空接口

Go中提供了一個空接口,空接口就是接口中沒有定義任何的方法,里面是空的。空接口相當于Java中的Object對象,是所有類型的父類型,Go中的空接口就是所有類型的父類型。

// 定義空接口變量
interfaceVar interface{}

空接口可以作為一個方法的參數,這個參數叫做:空接口變量。空接口變量可以接收任意的數據類型,從而就可以實現同一個方法可以處理多種類型的參數。

package mainimport "fmt"func demo(interfaceVar interface{}) {switch v := interfaceVar.(type) {case int:fmt.Println("int 類型", v)case string:fmt.Println("string 類型", v)default:fmt.Println("都不滿足的類型")}
}func main() {// 定義int類型myInt := 10demo(myInt)// 定義string類型myStr := "hello world"demo(myStr)
}
(5)類型切換和斷言

Go語言中,提供了一種特殊的語法,叫做:類型切換類型斷言。語法格式:

// 類型切換和類型斷言
v := interfaceVar.(T)// interfaceVar 表示接口變量
// T 表示數據類型
// v 是一個變量,具體來說是一個動態類型變量,它的類型會根據 interfaceVar.(T) 檢測出來的類型變化
// 當 v 的類型和 case 類型匹配時候,那么 v 變量就會被賦值對應類型的數據值

上面表達式用在switch結構里面,能夠動態的檢查接口變量interfaceVar的具體類型,并且將變量的值賦值給變量v

類型切換和類型斷言的代碼執行規則,我理解大概是這樣的:

1、首先進行類型切換,通過 interfaceVar.(T),獲取到具體的類型
2、將獲取到具體類型賦值給 v 變量
3、v 變量的類型再和 case 中的類型進行匹配
4、如果 v 能夠匹配上 case 的類型,則將對應類型的值賦值給 v 變量

案例代碼:

package mainimport "fmt"func demo(interfaceVar interface{}) {switch v := interfaceVar.(type) {case int:fmt.Println("int 類型", v)case string:fmt.Println("string 類型", v)default:fmt.Println("都不滿足的類型")}
}func main() {// 定義int類型myInt := 10demo(myInt)// 定義string類型myStr := "hello world"demo(myStr)// 定義 float 類型myFloat := 3.14demo(myFloat)
}
1.3.2、通用接口

go中的通用接口,需要和泛型結合使用,這樣才可以定義一個通用的接口,讓所有的數據類型都適用,這就是通用接口。后續介紹泛型時候,在一起介紹通用接口。

1.4、泛型

Go語言在1.18版本中引入泛型的概念。泛型定義的語法格式如下所示:

// 泛型定義
[泛型參數 約束類型1 | 約束類型2...]// 舉個例子:
func sum[T int | float32](a,b T) T {// 方法體
}

類型約束是指:當前泛型可以接收哪些數據類型,如果不是這里面的類型,那么就無法使用對應的方法、函數之類的。

上面就是定義泛型時候的語法格式,那要如何使用呢???

在使用泛型的時候,可以有兩種方式:

  • 第一種方式:使用時候指定具體的數據類型。
  • 第二種方式:不指定類型,讓編譯期自動推斷類型。
package mainimport "fmt"// 定義泛型方法
func sum[T int | float32](a, b T) T {return a + b
}func main() {// 計算 int 類型ans := sum(1, 2)fmt.Println(ans)// 主動指定類型ans2 := sum[float32](3.14, 2.86)fmt.Println(ans2)
}

泛型結構的使用注意事項:

  • 泛型不能用在基本類型上。
  • 泛型不能進行類型斷言。
  • 匿名結構中,不允許使用泛型。
  • 匿名函數不支持自定義泛型。
  • 方法不能使用泛型。

為什么方法上面不能使用泛型呢???

我是這么理解的,因為Go中不允許方法重載,所以如果方法上面使用了泛型,那不就是相當于Go中會存在兩個相同名稱的方法了嗎?這就和Go中不允許方法重載的定義相違背了,所以也就不允許方法使用泛型了。

1.5、類型

Go語言中的類型,是一種靜態強類型,什么是靜態呢???

靜態強類型

靜態是指:Go中的數據類型一旦定義出來之后,在編譯期期間就已經確定了,后續運行程序的時候,就不能夠改變類型了。

強類型是指:當我們程序員在寫代碼的時候,如果改變了數據類型,那么編譯期就會馬上提示程序員,語法錯了,不能修改類型。

var a int = 1
// 編譯不通過,因為前后類型不一致
a = "2"

類型后置

Go語言中,所有的數據類型都是寫在名稱后面的,這是因為寫在變量名稱后面,能夠讓程序的可讀性更強,類型太多的時候不至于看著混亂。

var 變量名稱 數據類型

類型聲明

Go語言中,使用type關鍵字聲明類型,自定義類型也是使用type關鍵字定義的。

// 聲明類型
type 類型名稱 數據類型

類型轉換

Go語言中,沒有類型Java語言中的隱式類型轉換的功能,Go語言只有顯式類型轉換,也就是說,必須讓程序員在代碼中主動的進行類型轉換。

package mainimport "fmt"func main() {var f float64 = 3.14// 強制類型轉換var f2 int = int(f)fmt.Println(f2)
}

以上就是Go語言中函數、方法、泛型、接口相關的學習筆記內容。

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

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

相關文章

LLM筆記(九)KV緩存調研

KV 緩存 (Key-Value Cache) 技術詳解 KV 緩存&#xff08;Key-Value Cache&#xff09;是在 Transformer 模型&#xff08;尤其是 Decoder-Only 架構或 Encoder-Decoder 架構的 Decoder 部分&#xff09;進行自回歸 (auto-regressive) 推理生成序列時&#xff0c;一種至關重要…

【Boost搜索引擎】構建Boost站內搜索引擎實踐

目錄 1. 搜索引擎的相關宏觀原理 2. 正排索引 vs 倒排索引 - 搜索引擎具體原理 3. 編寫數據去標簽與數據清洗的模塊 Parser 去標簽 編寫parser 用boost枚舉文件名 解析html 提取title ?編輯 去標簽 構建URL 將解析內容寫入文件中 4. 編寫建立索引的模塊 Index 建…

LeetCode 熱題 100 1.兩數之和

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 思路一暴力遍歷&#xff1a; 代碼&#xff1a; 暴力遍歷Java代碼&#xff1a; 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 1. 兩數之和 - 力扣&#xff08;LeetC…

基于LSTM-GARCH混合模型的黃金價格波動率預測:信用降級事件沖擊評估

摘要&#xff1a;本文構建多維度量化分析框架&#xff0c;對近期黃金市場波動進行技術解構。通過主權信用評級調整、地緣風險及宏觀經濟數據等公開信息源&#xff0c;運用統計學習模型解析市場驅動因素&#xff0c;避免主觀預判。文中所有技術分析均基于歷史數據回測&#xff0…

分布式與集群:概念、區別與協同

分布式與集群:概念、區別與協同 在分布式系統與云計算領域,分布式(Distributed)和集群(Cluster)是兩個高頻出現的核心概念。它們常被混淆,但本質上屬于不同維度的設計思想。本文將從定義、分類、實際應用及協同關系四個層面,結合 Dubbo、Git、Hadoop 等典型案例,系統…

Prometheus實戰教程:k8s平臺-Mysql監控案例

配置文件優化后的 Prometheus 自動發現 MySQL 實例的完整 YAML 文件。該配置包括&#xff1a; MySQL Exporter 部署&#xff1a;使用 ConfigMap 提供 MySQL 連接信息。Prometheus 自動發現&#xff1a;通過 Kubernetes 服務發現自動抓取 MySQL 實例。 1、mysql 配置文件 &…

基于區塊鏈技術的智能汽車診斷與性能分析

我是穿拖鞋的漢子&#xff0c;魔都中堅持長期主義的汽車電子工程師。 老規矩&#xff0c;分享一段喜歡的文字&#xff0c;避免自己成為高知識低文化的工程師&#xff1a; 鈍感力的“鈍”&#xff0c;不是木訥、遲鈍&#xff0c;而是直面困境的韌勁和耐力&#xff0c;是面對外界…

文字溢出省略號顯示

一、 單行文字溢出、省略號顯示 二、 多行文字溢出&#xff0c;省略號顯示 有較大的兼容性問題&#xff0c;適用于Webkit為內核的瀏覽器軟件&#xff0c;或者移動端的&#xff08;大部分也是webkit&#xff09; 此效果建議后端人員開發 三、圖片底側空白縫隙的修復技巧&#…

JavaScript 中使用 Elasticsearch 的正確方式,第一部分

作者&#xff1a;來自 Elastic Jeffrey Rengifo 講解如何用 JavaScript 創建一個可用于生產環境的 Elasticsearch 后端。 想獲得 Elastic 認證&#xff1f;看看下一期 Elasticsearch 工程師培訓什么時候開始吧&#xff01; Elasticsearch 擁有大量新功能&#xff0c;能幫助你…

RAG-MCP:突破大模型工具調用瓶頸,告別Prompt膨脹

大語言模型&#xff08;LLM&#xff09;的浪潮正席卷全球&#xff0c;其強大的自然語言理解、生成和推理能力&#xff0c;為各行各業帶來了前所未有的機遇。然而&#xff0c;正如我們在之前的探討中多次提及&#xff0c;LLM并非萬能。它們受限于訓練數據的時效性和范圍&#xf…

鴻蒙OSUniApp制作一個小巧的圖片瀏覽器#三方框架 #Uniapp

利用UniApp制作一個小巧的圖片瀏覽器 最近接了個需求&#xff0c;要求做一個輕量級的圖片瀏覽工具&#xff0c;考慮到多端適配的問題&#xff0c;果斷選擇了UniApp作為開發框架。本文記錄了我從0到1的開發過程&#xff0c;希望能給有類似需求的小伙伴一些參考。 前言 移動互聯…

Python爬蟲實戰:獲取taobao網最新rtx5060ti顯卡銷量數據并分析,為消費者做參考

一、系統定義與技術架構 1.1 系統定義 本系統是基于 Python 開發的電商數據采集與分析工具,旨在通過模擬用戶行為實現淘寶平臺 50 系列顯卡(以 RTX 5060 Ti 為例)銷售數據的自動化獲取、清洗、分析及可視化。核心功能包括: 自動登錄:通過 Selenium 模擬瀏覽器操作完成賬…

OCframework編譯Swift

建一個OC的framework&#xff1a; 需要對外暴露的OC文件&#xff0c;需要放到OC的.h文件中 framework中&#xff0c;OC類&#xff0c;調用framework中的Swift類&#xff1a; #import "WowAudioFocus/WowAudioFocus-Swift.h" //02 #import "{工程名}/{工程…

每日算法 -【Swift 算法】Two Sum 問題:從暴力解法到最優解法的演進

【Swift 算法】Two Sum 問題&#xff1a;從暴力解法到最優解法的演進 本文通過“Two Sum”問題&#xff0c;帶你了解如何從最直觀的暴力解法&#xff0c;逐步優化到高效的哈希表解法&#xff0c;并對兩者進行對比&#xff0c;適合算法入門和面試準備。 &#x1f4a1; 問題描述 …

【保姆級】Nginx簡介以及安裝

Nginx簡介 ? Nginx是一個高性能的HTTP和反向代理web服務器&#xff0c;同時也提供了IMAP/POP3/SMTP服務。Nginx是由伊戈爾賽索耶夫為俄羅斯訪問量第二的Rambler.ru站點&#xff08;俄文&#xff1a;Рамблер&#xff09;開發的&#xff0c;第一個公開版本0.1.0發布于20…

C++(25): 標準庫 <deque>

目錄 1、 核心概念 2. 基本語法 3. 特點 4. 特有成員函數 5. 內存與性能 6. 示例代碼 7. 成員函數列表 8. 使用場景 9. 注意事項 1、 核心概念 雙端隊列(Double-Ended Queue,deque) 是一種允許在隊列頭部和尾部高效插入和刪除元素的線性數據結構,同時支持隨機訪問。…

軟件設計師關系代數和元組演算(關聯、笛卡爾積、除、映射、分段等問題)考點分析——求三連

一、考點分值占比與趨勢分析 綜合知識歷年統計表 年份考題數量分值分值占比考察重點2018334%自然連接、投影、選擇2019222.67%笛卡爾積、條件篩選2020111.33%屬性列計算2021334%關系運算綜合應用2022222.67%元組演算表達式2023222.67%差運算、連接類型2024111.33%除法運算應用…

卸載云樞(MacOS 版)

刪除 APP 和相關文件 sudo chflags -R noschg /Applications/Yunshu.app 2>/dev/null sudo rm -rf /Applications/Yunshu.app sudo rm -rf /Library/Application\ Support/EagleCloud sudo rm -rf /Library/LaunchAgents/com.eagleyun.endpoint.agent.plist sudo rm -rf /L…

在 Ubuntu 20.04 中使用 init.d 或者systemd實現開機自動執行腳本

Ubuntu 20 默認使用的是 systemd 系統管理器&#xff0c;但傳統的 SysV Init&#xff08;/etc/init.d/&#xff09;腳本依然兼容并可用。本文將介紹如何通過 init.d 寫腳本來在開機時自動設置某個 GPIO&#xff08;如 GPIO407&#xff09;為高電平&#xff0c;適用于嵌入式系統…

蘋果的人工智能領域慢熱

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…