【啟程Golang之旅】深入解析函數的奧秘與技巧

歡迎來到Golang的世界!在當今快節奏的軟件開發領域,選擇一種高效、簡潔的編程語言至關重要。而在這方面,Golang(又稱Go)無疑是一個備受矚目的選擇。在本文中,帶領您探索Golang的世界,一步步地了解這門語言的基礎知識和實用技巧。

目錄

初識函數

引入包

init函數

匿名函數

閉包

defer關鍵字

系統函數

錯誤處理


初識函數

為完成某一功能的程序指令(語句)的集合稱為函數,函數的作用就是提高代碼的復用性和可維護性,減少代碼的冗余。接下來我們舉一個簡單的例子,看一看函數如何進行處理和調用:

package main
import "fmt"
/*	函數基本格式func 函數名(參數列表) (返回值列表) {函數體return 返回值列表}
*/
// 求和函數
func cal(a, b int) int {return a + b
}
func main() {sum := cal(1, 2)fmt.Println(sum) // 3
}

函數有一些區別于其他語言的一些細節所在,接下來本文將對這些細節及其所起作用一一講解:

函數名

1)遵循標識符命名規范:見名知意addNum,駝峰命名addNum

2)首字母不能是數字

3)首字母大寫該函數可以被本包文件和其它包文件使用(類似public)

4)首學母小寫只能被本包文件使用,其它包文件不能使用(類似private)

形參列表

1)形參列表:個數:可以是一個參數,可以是n個參數,可以是0個參數

2)形式參數列表:作用:接收外來的數據

3)實際參數:實際傳入的數據

返回值類型列表

可以是多個,根據具體進行進行返回。

package main
import "fmt"
// 求和函數
func cal(a, b int) (int, int) {result1 := a + bresult2 := a - breturn result1, result2
}
func main() {sum1, sum2 := cal(1, 2)// 如果不想接收第二個值,可以使用下劃線占位進行忽略//sum1, _ := cal(1, 2)fmt.Println(sum1, sum2) // 3  -1
}

函數不支持重載

在C++、Java(從C++11開始支持方法重載)等語言中。它允許程序員在相同的作用域內定義多個具有相同名稱但參數列表(參數類型、參數個數或參數順序)不同的函數。

// Go語言中不支持函數重載,但可以使用不同的函數名  
func printInt(x int) {  fmt.Println("Printing an integer:", x)  
}  
func printFloat(x float64) {  fmt.Println("Printing a float:", x)  
}  func main() {  printInt(10)      // 調用printInt  printFloat(10.5)  // 調用printFloat  
} 

支持可變參數

golang中支持可變參數(如果你希望函數帶有可變數量的參數)

package main
import "fmt"
// 定義一個函數,函數參數為:可變參數 ... 參數的數量可變
// args...int 可以傳入任意多個數量的int類型的數據,傳入0個,1個...n個
func test(args ...int) {// 函數內部處理可變參數的時候,可將可變參數當作切片來處理// 遍歷可變參數for i := 1; i < len(args); i++ {fmt.Println(i, args[i])}
}func main() {test(1, 2) // 1 2fmt.Println("-----------")test() // 空
}

值拷貝

基本數據類型和數組默認都是值傳遞的即進行值拷貝。在函數內修改不會影響到原來的值。

package main
import "fmt"
func test(num int) {num = 30fmt.Println(num)
}func main() {var num int = 10test(num) // 30fmt.Println(num) // 10
}

引用傳遞

以值傳遞的方式的數據類型,如果希望在函數內的變量能夠修改函數外的變量,可以傳入變量的地址&,函數內以指針的方式操作變量,從效果來看類似引用傳遞。

package main
import "fmt"
func test(num *int) {*num = 30fmt.Println(num)
}func main() {var num int = 10fmt.Println(&num) // 0xc00000a0c8test(&num)        // 調用test函數,將num的地址作為參數傳遞給test函數,test函數中修改num的值,結果為0xc00000a0c8fmt.Println(num)  // 30
}

賦值變量

在Go中,函數世是一種數據類型,可以賦值給一個變量,則該變量就是一個函數類型的變量了。通過該變量可以對函數調用。.

package main
import "fmt"
// 定義函數
func test(num int) {fmt.Println(num)
}func main() {// 函數也是一種數據類型,可以賦值給變量a := testfmt.Printf("a的類型是: %T, test函數的類型是:%T \n", a, test) // a的類型是: func(int), test函數的類型是:func(int)// 通過賦值變量,調用函數a(10) // 10
}

形參調用

函數既然是一種數據類型,因此在Go中,函數可以作為形參,并且調用(把函數本身當做一種數據類型)

package main
import "fmt"
// 定義函數
func test(num int) {fmt.Println(num)
}
// 定義函數,把函數作為參數傳遞給另一個函數
func test2(num int, testfunc func(int)) {fmt.Println("---")testfunc(num)
}func main() {// 函數也是一種數據類型,可以賦值給變量a := testfmt.Printf("a的類型是: %T, test函數的類型是:%T \n", a, test) // a的類型是: func(int), test函數的類型是:func(int)// 通過賦值變量,調用函數a(10) // 10// 函數作為參數傳遞給另一個函數test2(10, test) // --- 10
}

自定義數據類型

為了簡化數據類型定義,Go支持自定義數據類型基本語法,type自定義數據類型名數據類型

可以理解為:相當于起了一個別名例如:typemylnt int -----》這時mylnt就等價int來使用了。

// 自定義數據類型(相當于起別名):給int類型起了別名叫myInt類型
type myInt int
var num1 myInt = 10
fmt.Println(num1) // 10//var num2 int = 10
//num2 = num1 // 雖然是別名,但是在go語言中,別名是不能進行隱式轉換的,還是認為myInt與int類型不同
package main
import "fmt"
// 定義函數
func test(num int) {fmt.Println(num)
}
// 定義函數,把函數作為參數傳遞給另一個函數
// 自定義數據類型
type myfunc func(int)
func test2(num int, testfunc myfunc) {fmt.Println("---")testfunc(num)
}func main() {// 函數也是一種數據類型,可以賦值給變量a := testfmt.Printf("a的類型是: %T, test函數的類型是:%T \n", a, test) // a的類型是: func(int), test函數的類型是:func(int)// 通過賦值變量,調用函數a(10) // 10// 函數作為參數傳遞給另一個函數test2(10, test) // --- 10
}

當然這里還支持函數返回值命名,里面順序無所謂,具體如下代碼示例:

package main
import "fmt"
func test(num1 int, num2 int) (sum int, sub int) {sum = num1 + num2sub = num1 - num2return
}func main() {sum, sub := test(10, 2)fmt.Println(sum, sub) // 12 8
}

引入包

在Go語言中,包(package)是一個非常重要的概念,它用于組織和管理代碼。

包的概念

1)組織代碼:包是Go語言中代碼的基本組織單元。它將相關的函數、類型、變量和常量等組合在一起,形成一個邏輯上的整體。

2)命名空間:每個包都有其自己的命名空間,包內的標識符(如函數名、類型名、變量名等)在該包內是唯一的,但在不同的包中可以重名。通過包名可以區分和引用不同包中的標識符。

3)封裝性:包可以隱藏其內部實現細節,只對外暴露必要的接口。這有助于保護代碼的封裝性,減少不同模塊之間的耦合度。

使用意義

1)代碼復用:通過將代碼組織成包,可以方便地在不同的項目或模塊中復用這些代碼。只需要將包導入(import)到需要使用的地方,就可以使用其中的函數、類型和變量等。

2)模塊化管理:Go語言的包機制支持模塊化管理,可以將大型項目拆分成多個小模塊(即包),每個模塊負責實現特定的功能。這樣可以提高代碼的可讀性和可維護性,降低項目的復雜度。

3)類型安全:由于每個包都有自己的命名空間,因此可以避免不同包中的標識符重名導致的類型沖突問題。這有助于提高代碼的類型安全性。

4)隱藏實現細節:通過將實現細節封裝在包內部,只對外暴露必要的接口,可以隱藏實現細節,降低外部對內部實現的依賴和耦合度。這有助于提高代碼的可維護性和可擴展性。

5)遵循最佳實踐:Go語言的包機制鼓勵開發者遵循最佳實踐,如將相關的函數和類型組織在同一個包中,使用統一的命名規范等。這有助于提高代碼的可讀性和可維護性。

以下是導包后調用的基礎案例:

我們在導包的時候,也是需要關注一些細節方面的內容,方便我們快速導包使用,細節如下:

1)package進行包的聲明,建議:包的聲明這個包和所在的文件夾同名

2)main包是程序的入口包,一般main函數會放在這個包下

3)打包語法:package 包名

4)引l入包的語法:import"包的路徑”包名是從$GOPATH/src/后開始計算的,使用/進行路徑分隔。

5)如果有多個包,建議一次性導入,格式如下:

????????import(

????????????????"fmt"

????????????????"dbutils"

????????)

6)在函數調用的時候前面要定位到所在的包

7)首字母大寫,函數可以被其它包訪問

8)一個目錄下不能有重復的函數

9)包名和文件夾的名字,可以不一樣

10)一個目錄下的同級文件歸屬一個包

11)在程序層面,所有使用相同package包名的源文件組成的代碼模塊,在源文件層面就是一個文件夾

當然也可以給包起別名,起完別名之后原來的包名就不能再使用了:

init函數

初始化函數,可以用來進行一些初始化的操作每一個源文件都可以包含一個init函數,該函數會在main函數執行前,被Go運行框架調用。示例代碼如下所示:

全局遍歷、init函數、main函數的執行順序流程如下:

多個init函數情況,先執行外包中的init函數,最后執行main函數中的init函數,示例如下:

匿名函數

go語言支持匿名函數,如果我們某個函數只是希望使用一次,可以考慮使用匿名函數,以下是使用匿名函數的使用方式:

定義匿名函數時就直接調用,這種方式匿名函數只能調用一次:

package main
import "fmt"
func main() {// 定義匿名函數result := func(num1 int, num2 int) int {return num1 + num2}(10, 3)fmt.Println(result) // 13
}

將匿名函數賦給一個變量(該變量就是函數變量了),再通過該變量來調用匿名函數:

package main
import "fmt"
func main() {// 將匿名函數賦值給變量,然后通過變量調用匿名函數sub := func(a, b int) int {return a - b}// 調用匿名函數result := sub(10, 5)fmt.Println(result) // 5
}

將匿名函數作為全局變量使用:

package main
import "fmt"
// 設置全局匿名函數
var sub = func(a, b int) int {return a - b
}func main() {// 調用匿名函數result := sub(10, 5)fmt.Println(result) // 5
}

閉包

閉包就是一個函數和與其相關的引|用環境組合的一個整體。

閉包的本質:是一個匿名函數,只是這個函數引入外界的變量 / 參數匿名函數 + 引用的變量 / 參數 = 閉包,示例代碼如下:

package main
import "fmt"
// 函數求和,函數的名字是getSum,參數為空
// getSum返回一個函數,這個函數是int類型的參數,返回值也是int類型
func getSum() func(int) int {var sum int = 0return func(num int) int {sum += numreturn sum}
}func main() {f := getSum()// 可以看到匿名函數中引用的那邊變量會一直保存再內存中,可以一直使用fmt.Println(f(1)) // 1fmt.Println(f(2)) // 3fmt.Println(f(3)) // 6
}

閉包的特點:返回的是一個匿名函數,但是這個匿名函數引用到函數外的變量/參數,因此這個匿名函數就和變量/參數形成一個整體,構成閉包。包中使用的變量/參數會一直保存在內存中,所以會一直使用,這就意味著閉包不可濫用。

defer關鍵字

在函數中,程序員經常需要創建資源,為了在函數執行完畢后,及時的釋放資源,Go的設計者提供defer關鍵字,接下來通過如下代碼進行講解:

遇到defer關鍵字會將后面的代碼語句壓入棧中,也會將相關的值同時拷貝入棧中,不會隨著函數后面的變化而變化。代碼如下:

package main
import "fmt"
func add(num1, num2 int) int {// 在go中,程序遇到defer關鍵字,不會立即執行defer后面的語句,而是將defer后面的語句放入到棧中,然后執行函數后面的語句。defer fmt.Println("num1 = ", num1)defer fmt.Println("num2 = ", num2)// 棧的特點是先進后出,所以defer后面的語句會先執行// 在函數執行完畢后,從棧中取出語句開始執行,按照先進后出的順序執行sum := num1 + num2fmt.Println("sum = ", sum)return sum
}
func main() {fmt.Println(add(1, 2))
}

最終得到的結果如下所示:

defer應用場景:比如你想關閉某個使用的資源,在使用的時候直接隨手defer,因為defer有延遲執行機制(函數執行完畢再執行defer壓入棧的語句),所以你用完隨手寫了關閉,比較省心,省事!

系統函數

系統函數是一個相對模糊的概念,它可以指代任何與底層系統交互或執行特定系統級別任務的函數。在Go語言中,這些函數可能來自標準庫、第三方庫、通過系統調用實現的功能或者內置的函數,接下來我們就講解一下go語言中常見的內置函數,使用內置函數也不用導包的,直接用就行:

len(str):統計字符串的長度,按字節進行統計

func main() {// 統計字符串的長度,按字節進行統計str := "hello world"fmt.Println(len(str)) // 11
}

r:=[]rune(str):字符串遍歷

func main() {str := "hello world"// 對字符串進行變量// 方式1:利用鍵值循環:for - rangefor i, value := range str {fmt.Printf("索引為:%d, 具體的值為:%c \n", i, value)}fmt.Println("---------------------------------")// 方式2:利用 r:=[]rune(str)r := []rune(str)for i := 0; i < len(r); i++ {fmt.Printf("索引為:%d, 具體的值為:%c \n", i, r[i])}
}

最終得到的結果如下所示:

n, err := strconv.Atoi("66"):字符串轉整數;str = strconv.ltoa(6887):整數轉字符串

func main() {// 字符串轉整數num1, _ := strconv.Atoi("123")fmt.Println(num1) // 123// 整數轉字符串num2 := strconv.Itoa(123)fmt.Println(num2) // "123"
}

strings.Contains("javaandgolang", "go"):查找子串是否在指定的字符串中

func main() {// 查找子串是否在指定的字符串中result := strings.Contains("javaandgolang", "go")fmt.Println(result) // true
}

strings.Count("javaandgolang","a"):統計一個字符串有幾個指定的子串

func main() {// 查找子串是否在指定的字符串中result := strings.Count("javaandgolang", "a")fmt.Println(result) // 4
}

fmt.Println(strings.EqualFold("go", "Go")):不區分大小寫的字符串比較

func main() {fmt.Println(strings.EqualFold("go", "Go")) // true
}

strings.Index("javaandgolang", "a"):返回子串在字符串第一次出現的索引值,如果沒有返回-1

func main() {result := strings.Index("javaandgolang", "a")fmt.Println(result) // 1
}

當然下面還有一些函數,這里就不再一一演示了:

strings.Replace("goandjavagogo", "go","golang", n):字符串的替換,n表示替換幾個

strings.Split("go-python-java", "-"):按照指定的某個字符,為分割標識,將一個學符串拆分成字符串數組

strings.ToLower("Go") // go;strings.ToUpper"go") //Go:字符串的字母進行大小寫的轉換

strings.TrimSpace("?? go and java??? "):將字符串左右兩邊的空格去掉

strings.Trim("~golang~ ", " ~"):將字符串左右兩邊指定的字符去掉

strings.TrimLeft("~golang~ ", " ~")strings.TrimRight("~golang~ ", " ~"):指定字符兩邊去掉

strings.HasPrefix("http://java.sun.com/jsp/jstl/fmt", "http"):判斷字符串是否以指定的字符串開頭

當然go語言還內置了時間函數,這里進行一個簡單的演示:

package main
import ("fmt""time"
)
func main() {// 日期時間函數now := time.Now()// Now() 是一個結構體,類型是time.Time, 返回的是當前時間// 2024-05-26 16:05:18.4238005 +0800 CST m=+0.000660501 ~~~ 對應的類型為: time.Timefmt.Printf("%v ~~~ 對應的類型為: %T\n", now, now)// 獲取年月日fmt.Printf("年: %d\n", now.Year())  // 2024fmt.Printf("月: %d\n", now.Month()) // 5fmt.Printf("日: %d\n", now.Day())   // 26// 獲取當前年月日時分秒的字符串 Format()函數是結構體的方法,作用是格式化時間fmt.Printf("年月日時分秒: %s\n", now.Format("2006-01-02 15:04:05")) // 2024-05-26 16:05:18
}

最終達到的效果如下所示:

錯誤處理

當函數出現運行錯誤的時候,會導致程序被中斷,是無法繼續執行后續代碼的,所以我們需要對錯誤進行一個處理,以下是程序出現錯誤時的情況:

在Go語言中,deferrecover是兩個與函數延遲執行和異常處理相關的關鍵字。它們主要用于錯誤處理和資源清理等場景。

package main
import "fmt"
func test() {// 利用defer+recover機制,捕獲異常,defer后加上匿名函數的調用defer func() {// 調用recover()函數,捕獲異常err := recover()if err != nil {// 捕獲異常后,執行相應的處理邏輯fmt.Println("錯誤已經捕獲")fmt.Println("捕獲異常:", err)}}()num1 := 10num2 := 0result := num1 / num2fmt.Println(result)
}func main() {test()fmt.Println("上述邏輯正常,開始執行下面的代碼~")fmt.Println("main函數執行完畢")
}

最終實現的效果如下所示:

如果想自定義錯誤的話,可以采用下面的方式進行:

package main
import ("errors""fmt"
)
func test() (err error) {num1 := 10num2 := 0// 自定義錯誤if num2 == 0 {// 拋出自定義錯誤return errors.New("除數不能為0")} else {result := num1 / num2fmt.Println(result)// 如果沒有錯誤,返回零值return nil}
}func main() {err := test()if err != nil {fmt.Println("自定義錯誤", err)}fmt.Println("上述邏輯正常,開始執行下面的代碼~")fmt.Println("main函數執行完畢")
}

最終實現的結果如下所示:

有一種情況:程序出現錯誤以后,后續代碼就沒有必要執行,想讓程序中斷,退出程序:借助:builtin包下內置函數:panic

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

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

相關文章

【全開源】海報在線制作系統源碼(ThinkPHP+FastAdmin+UniApp)

打造個性化創意海報的利器 引言 在數字化時代&#xff0c;海報作為一種重要的宣傳媒介&#xff0c;其設計質量和效率直接影響著宣傳效果。為了滿足廣大用戶對于個性化、高效制作海報的需求&#xff0c;海報在線制作系統源碼應運而生。本文將詳細介紹海報在線制作系統源碼的特…

AbMole - 腫瘤發展與免疫器官的“舞蹈”:一場細胞層面的時間賽跑

在生物醫學領域&#xff0c;腫瘤與免疫系統之間的相互作用一直是研究的熱點話題。腫瘤細胞不是孤立存在的&#xff0c;它們與宿主的免疫系統進行著一場復雜的“舞蹈”。 最近&#xff0c;一項發表在《Molecular & Cellular Proteomics》雜志上的研究&#xff0c;為我們揭開…

【C++】二分查找算法

1.題目 2.算法思路 暴力解法&#xff1a;可以將數組遍歷一遍&#xff0c;就可以找到。時間復雜度為O(n)。不算太差&#xff0c;可以接受。 但是有更優秀的解法&#xff1a; 就是二分查找算法。 算法的特點&#xff1a;我們所查找的“數組”具有二段性。這里的二段性不一定有…

頭歌OpenGauss數據庫-L.應用開發(Python)-選做

第1關:簡單查詢 編程要求 正確使用 psycopg2 ,查詢金融應用場景數據庫 finance 的 client 表(客戶表)中郵箱不為空的客戶信息,列出客戶姓名,郵箱和電話.一個展示結果的示例如下(字體顏色不是編程要求): 注意:你要連接到finance數據庫上(后面第2-6關也是連接這個數據庫)…

【C/C++】詳解關聯容器map的使用

&#x1f517; 運行環境&#xff1a;Matlab &#x1f6a9; 撰寫作者&#xff1a;左手の明天 &#x1f947; 精選專欄&#xff1a;《python》 &#x1f525; 推薦專欄&#xff1a;《算法研究》 &#x1f510;#### 防偽水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

mpv常用快捷鍵

1 mpv mpv是Linux下的一個開源視頻播放器&#xff0c;使用Manjaro的話安裝方式如下&#xff1a; paru -S mpv2 常用快捷鍵 q&#xff1a;推出w/e&#xff1a;視頻縮放r/t&#xff1a;調整字幕位置u&#xff1a;開啟/關閉ass/ssa字幕覆蓋i&#xff1a;顯示當前播放的視頻信息…

Oracle 并行和 session 數量的

這也就是為什么我們指定parallel為4&#xff0c;而實際并行度為8的原因。 insert create index&#xff0c;發現并行數都是加倍的 Indexes seem always created with parallel degree 1 during import as seen from a sqlfile. The sql file shows content like: CREATE INDE…

求平方數 1 到 N 之間所有正整數的平方數

概念&#xff1a; 平方數的概念&#xff1a; 平方數是指一個數的平方等于另一個數的數&#xff0c;具有正平方數和負平方數&#xff0c;其性質和運用在多領域中具有重要意義&#xff0c;如幾何、自然科學、計算機科學和物理學。平方數的計算和運用在多領域中常見&#xff0c;例…

滑不動窗口的秘密—— “滑動窗口“算法 (Java版)

本篇會加入個人的所謂魚式瘋言 ??????魚式瘋言:??????此瘋言非彼瘋言 而是理解過并總結出來通俗易懂的大白話, 小編會盡可能的在每個概念后插入魚式瘋言,幫助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能說的不是那么嚴謹.但小編初心是能讓更多人能接…

《python編程從入門到實踐》day39

# 昨日知識點回顧 創建主頁、繼承模版、顯示特定主題頁面 # view.py from django.shortcuts import render# 導入所需數據相關聯的模型 from .models import Topic# Create your views here. def index(request):"""學習筆記的主頁"""#…

Java進階學習筆記13——抽象類

認識抽象類&#xff1a; 當我們在做子類共性功能抽取的時候&#xff0c;有些方法在父類中并沒有具體的體現&#xff0c;這個時候就需要抽象類了。在Java中&#xff0c;一個沒有方法體的方法應該定義為抽象方法&#xff0c;而類中如果有抽象方法&#xff0c;該類就定義為抽象類…

ISCC2024個人挑戰賽WP-迷失之門

&#xff08;非官方解&#xff0c;以下內容均互聯網收集的信息和個人思路&#xff0c;僅供學習參考&#xff09; 迷失之門 方法一&#xff1a; IDA看一下 check函數邏輯 進入到check2函數 R鍵將ascii碼轉字符&#xff0c;寫出逆向腳本 #include <stdio.h> #include &l…

嵌入式0基礎開始學習 Ⅱ 數據結構(7)小結練習

1,如果使用比較高效的算法判斷單鏈表有沒有環的算法中&#xff0c;至少需要幾個指針&#xff1f; A,1 B,2 C,3 D,4 2&#xff0c;以鏈接方式存儲的線性表(X1,X2,...,Xn),當訪問第i個元素的時間復雜度為? A,o(1) B,o(n) C,o(logn) Do(n) 3,下列鏈表中&…

Linux C++ Socket 套接字、select、poll、epoll 實例

文章目錄 1. 概述2. TCP 網絡編程實例2.1 服務器端2.2 客戶端2.3 運行截圖 3. I/O 模型3.1 阻塞式I/O模型3.2 非阻塞I/O模型3.3 I/O 復用模型3.4 信號驅動式I/O3.5 異步I/O模型 4. I/O復用之 select4.1 select 函數描述4.2 服務端代碼4.3 客戶端代碼4.4 運行截圖 5. I/O復用之 …

RocketMq局部順序消息

package com.ldj.rocketmq.producer;import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message;import java.nio.charset.StandardCharsets;/*** User: ldj* Date: 2024/5/26* Time: 15:09* Description: 局部順序消…

【Linux】$()中的內容與不加$()時有什么區別

$()中的內容與不加$()有什么區別&#xff0c;例如$(/usr/local/hadoop/bin/hadoop classpath)與/usr/local/hadoop/bin/hadoop classpath兩者有何區別&#xff1f;&#xff1f;&#xff1f; 關于這個問題&#xff0c;筆者建議可以參考如下文章&#xff1a; Linux—shell中$((…

css卡片翻轉 父元素翻轉子元素不翻轉效果

css卡片翻轉 父元素翻轉子元素不翻轉效果 vue <div class"moduleBox"><div class"headTitle"><span class"headName">大額案例</span></div><div class"moduleItem"><span class"module…

three.js判斷物體在人的前面,還是后面

three.js判斷物體在人的前面&#xff0c;還是后面 const player new THREE.Vectors(10, 0, 5); const mesh new THREE.Vectors(15, 0, 6);上面&#xff0c;兩個變量分別表示&#xff0c;玩家的位置&#xff0c;物體的位置。 從這發現&#xff0c;當玩家和物體的角度關系 小…

spring boot 整合j2cache 項目啟動警告 Redis mode [null] not defined. Using ‘single‘

好 之前的文章 spring boot 整合j2cache 基礎操作 在spring boot環境中整合了 j2cache 我們 項目啟動時 日志會有一個關鍵信息 Redis的模式 沒有定義 默認使用 single Redis 的這個模式有四種 大家可以自己去網上找一下 做個了解 不用很糾結 我們直接在 j2cache.properties …

一文讀懂Apollo客戶端配置加載流程

本文基于 apollo-client 2.1.0 版本源碼進行分析 Apollo 是攜程開源的配置中心&#xff0c;能夠集中化管理應用不同環境、不同集群的配置&#xff0c;配置修改后能夠實時推送到應用端&#xff0c;并且具備規范的權限、流程治理等特性。 Apollo支持4個維度管理Key-Value格式的配…