最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go異常處理、泛型和文件操作實例代碼

 更新時間:2025年12月04日 11:38:38   作者:Zfox_  
Go語言的異常處理機制與傳統(tǒng)的面向?qū)ο笳Z言(如 Java、C#)所使用的 try-catch 結(jié)構(gòu)有所不同,它采用了自己獨特的設(shè)計理念和方法,這篇文章主要介紹了Go異常處理、泛型和文件操作的相關(guān)資料,需要的朋友可以參考下

一:異常處理

go的異常處理可能是這門語言唯一的一個詬病了吧

由于 go 語言沒有捕獲異常的機制,導(dǎo)致每調(diào)一個函數(shù)都要接一下這個函數(shù)的 error

網(wǎng)上有個梗,叫做 error 是 go 的一等公民

常見的異常處理

向上拋

將錯誤交給上一級處理

一般是用于框架層,有些錯誤框架層面不能擅做決定,將錯誤向上拋不失為一個好的辦法

package main

import (
  "errors"
  "fmt"
)

func Parent() error {
  err := method() // 遇到錯誤向上拋
  return err
}
func method() error {
  return errors.New("出錯了")
}

func main() {
  fmt.Println(Parent())
}

中斷程序

遇到錯誤直接停止程序

這種一般是用于初始化,一旦初始化出現(xiàn)錯誤,程序繼續(xù)走下去也意義不大了,還不如中斷掉

package main

import (
  "fmt"
  "os"
)

func init() {
  // 讀取配置文件中,結(jié)果路徑錯了
  _, err := os.ReadFile("xxx")
  if err != nil {
    panic(err.Error())
  }
}

func main() {
  fmt.Println("啦啦啦")
}

恢復(fù)程序

我們可以在一個函數(shù)里面,使用一個 defer,可以實現(xiàn)對 panic 的捕獲

以至于出現(xiàn)錯誤不至于讓程序直接崩潰

這種一般也是框架層的異常處理所做的

package main

import (
  "fmt"
  "runtime/debug"
)

func read() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err) // 捕獲異常,打印錯誤信息
      // 打印錯誤的堆棧信息
      s := string(debug.Stack())
      fmt.Println(s)
    }
  }()
  var list = []int{2, 3}
  fmt.Println(list[2]) // 肯定會有一個panic
}

func main() {

  read()
}

當然,這個用于捕獲異常的 defer 的延遲函數(shù)可以在調(diào)用鏈路上的任何一個函數(shù)上,但是 main中 捕獲了會直接結(jié)束程序

  • panic 會層層向上拋,當前函數(shù)不處理,defer 放到 main 函數(shù)中也是會被處理的
  • 一旦 panic 發(fā)生,即使被 recover() 捕獲,當前調(diào)用棧的“正常流程”也會中斷

二:泛型

從 1.18 版本開始,Go 添加了對泛型的支持,即類型參數(shù)

泛型函數(shù)

如果我們要實現(xiàn)一個對int類型的求和函數(shù)

func add(a, b int) int {
  return a + b
}

但是這樣寫了之后,如果參數(shù)是 float 類型,int32 類型這些,就沒辦法使用了

難道要為每個類型都寫一個這樣的函數(shù)嗎?

顯然這就不合理

這個時候,泛型就上場了

func add[T int | float64 | int32](a, b T) T {
  return a + b
}

type Number interface {
	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
}

func plus[T Number](n1, n2 T) T {
	return n1 + n2
}

泛型結(jié)構(gòu)體

package main

import (
  "encoding/json"
  "fmt"
)

type Response[T any] struct {
  Code int    `json:"code"`
  Msg  string `json:"msg"`
  Data T      `json:"data"`
}

func main() {
  type User struct {
    Name string `json:"name"`
  }

  type UserInfo struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
  }

  //user := Response{
  //  Code: 0,
  //  Msg:  "成功",
  //  Data: User{
  //    Name: "楓楓",
  //  },
  //}
  //byteData, _ := json.Marshal(user)
  //fmt.Println(string(byteData))
  //userInfo := Response{
  //  Code: 0,
  //  Msg:  "成功",
  //  Data: UserInfo{
  //    Name: "楓楓",
  //    Age:  24,
  //  },
  //}
  //byteData, _ = json.Marshal(userInfo)
  //fmt.Println(string(byteData))

  var userResponse Response[User]
  json.Unmarshal([]byte(`{"code":0,"msg":"成功","data":{"name":"楓楓"}}`), &userResponse)
  fmt.Println(userResponse.Data.Name)
  var userInfoResponse Response[UserInfo]
  json.Unmarshal([]byte(`{"code":0,"msg":"成功","data":{"name":"楓楓","age":24}}`), &userInfoResponse)
  fmt.Println(userInfoResponse.Data.Name, userInfoResponse.Data.Age)
}

泛型切片

package main

type MySlice[T any] []T

func main() {
  var mySlice MySlice[string]
  mySlice = append(mySlice, "楓楓")
  var intSlice MySlice[int]
  intSlice = append(intSlice, 2)
}

泛型 map

package main

import "fmt"

type MyMap[K string | int, V any] map[K]V

func main() {
  var myMap = make(MyMap[string, string])
  myMap["name"] = "楓楓"
  fmt.Println(myMap)
}

三:文件操作

文件讀取

一次性讀取

byteData, _ := os.ReadFile("go_study/hello.txt")
fmt.Println(string(byteData))

獲取當前go文件的路徑

可以通過獲取當前 go 文件的路徑,然后用相對于當前 go 文件的路徑去打開文件

// GetCurrentFilePath 獲取當前文件路徑
func GetCurrentFilePath() string {
  _, file, _, _ := runtime.Caller(1)
  return file
}

分片讀

file, _ := os.Open("go_study/hello.txt")
defer file.Close()
for {
  buf := make([]byte, 1)
  _, err := file.Read(buf)
  if err == io.EOF {
    break
  }
  fmt.Printf("%s", buf)
}

帶緩沖讀

按行讀

file, _ := os.Open("go_study/hello.txt")
buf := bufio.NewReader(file)
for {
  line, _, err := buf.ReadLine()
  fmt.Println(string(line))
  if err != nil {
    break
  }
}

指定分割符

file, _ := os.Open("go_study/hello.txt")
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanWords) // 按照單詞讀
//scanner.Split(bufio.ScanLines) // 按照行讀
//scanner.Split(bufio.ScanRunes) // 按照中文字符讀
//scanner.Split(bufio.ScanBytes) // 按照字節(jié)讀讀,中文會亂碼

for scanner.Scan() {
  fmt.Println(scanner.Text())
}

文件寫入

一次性寫

err := os.WriteFile("go_study/file1.txt", []byte("這是內(nèi)容"), os.ModePerm)
fmt.Println(err)

文件的打開方式

常見的一些打開模式

// 如果文件不存在就創(chuàng)建
os.O_CREATE|os.O_WRONLY
// 追加寫
os.O_APPEND|os.O_WRONLY
// 可讀可寫
os.O_RDWR

完整的模式

const (
  O_RDONLY int = syscall.O_RDONLY // 只讀
  O_WRONLY int = syscall.O_WRONLY // 只寫
  O_RDWR   int = syscall.O_RDWR   // 讀寫
  
  O_APPEND int = syscall.O_APPEND // 追加
  O_CREATE int = syscall.O_CREAT  // 如果不存在就創(chuàng)建
  O_EXCL   int = syscall.O_EXCL   // 文件必須不存在
  O_SYNC   int = syscall.O_SYNC   // 同步打開
  O_TRUNC  int = syscall.O_TRUNC  // 打開時清空文件
)

文件的權(quán)限

主要用于linux系統(tǒng),在windows下這個參數(shù)會被無視,代表文件的模式和權(quán)限位

文件復(fù)制

io.Copy(dst Writer, src Reader) (written int64, err error)

將 src 文件的內(nèi)容復(fù)制到 dst 文件

read, _ := os.Open("go_study/file1.txt")
write, _ := os.Create("go_study/file3.txt") // 默認是 可讀可寫,不存在就創(chuàng)建,清空文件
n, err := io.Copy(write, read)
fmt.Println(n, err)

目錄操作

dir, _ := os.ReadDir("go_study")
for _, entry := range dir {
  info, _ := entry.Info()
  fmt.Println(entry.Name(), info.Size()) // 文件名,文件大小,單位比特
}

四:總結(jié)

到此這篇關(guān)于Go異常處理、泛型和文件操作的文章就介紹到這了,更多相關(guān)Go異常處理、泛型和文件操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語言計算兩個時間的時間差方法

    go語言計算兩個時間的時間差方法

    這篇文章主要介紹了go語言計算兩個時間的時間差方法,涉及Python操作時間的技巧,需要的朋友可以參考下
    2015-03-03
  • 深入理解Golang channel的應(yīng)用

    深入理解Golang channel的應(yīng)用

    channel是用于 goroutine 之間的同步、通信的數(shù)據(jù)結(jié)構(gòu)。它為程序員提供了更高一層次的抽象,封裝了更多的功能,這樣并發(fā)編程變得更加容易和安全。本文通過示例為大家詳細介紹了channel的應(yīng)用,需要的可以參考一下
    2022-10-10
  • GoLang調(diào)用鏈可視化go-callvis使用介紹

    GoLang調(diào)用鏈可視化go-callvis使用介紹

    與鏈路追蹤(Tracing)不同,Tracing關(guān)注復(fù)雜的分布式環(huán)境中各個服務(wù)節(jié)點間的調(diào)用關(guān)系,主要用于服務(wù)治理。而我們本次探索的代碼調(diào)用鏈路則是代碼方法級別的調(diào)用關(guān)系,主要用于代碼設(shè)計
    2023-02-02
  • Go語言中Slice常見陷阱與避免方法詳解

    Go語言中Slice常見陷阱與避免方法詳解

    這篇文章主要為大家詳細介紹的是 Go 語言中的 Slice 的常見陷阱以及如何避免這些錯誤,文中的示例代碼講解詳細,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-02-02
  • GO制作微信機器人的流程分析

    GO制作微信機器人的流程分析

    這篇文章主要介紹了利用go制作微信機器人,本文主要包括項目基礎(chǔ)配置及詳細代碼講解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • Go語言中的匿名結(jié)構(gòu)體用法實例

    Go語言中的匿名結(jié)構(gòu)體用法實例

    這篇文章主要介紹了Go語言中的匿名結(jié)構(gòu)體用法,實例分析了匿名結(jié)構(gòu)體的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Go項目關(guān)閉終端后停止運行的3種實用解決方案

    Go項目關(guān)閉終端后停止運行的3種實用解決方案

    在Go項目部署過程中,很多開發(fā)者都會遇到一個共性問題:通過終端啟動程序后,一旦關(guān)閉終端,程序就會隨之停止運行,本文將介紹3種可靠方案,徹底解決這一問題,確保Go程序在服務(wù)器上穩(wěn)定運行,需要的朋友可以參考下
    2025-08-08
  • Go實現(xiàn)超時控制的具體使用

    Go實現(xiàn)超時控制的具體使用

    本文主要介紹了Go中TimeoutControlWrapper實現(xiàn)超時控制,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-08-08
  • go語言beego框架jwt身份認證實現(xiàn)示例

    go語言beego框架jwt身份認證實現(xiàn)示例

    這篇文章主要為大家介紹了go語言beego框架jwt身份認證實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • 使用Golang實現(xiàn)Sm2加解密的代碼詳解

    使用Golang實現(xiàn)Sm2加解密的代碼詳解

    本文主要介紹了Go語言實現(xiàn)Sm2加解密的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03

最新評論

丹棱县| 尼勒克县| 琼中| 中方县| 绥化市| 龙岩市| 涿鹿县| 泽普县| 高密市| 平遥县| 苍山县| 永修县| 疏勒县| 靖江市| 封丘县| 涿州市| 徐汇区| 镇远县| 鸡东县| 扶绥县| 平罗县| 灌南县| 万源市| 库车县| 大荔县| 叶城县| 苗栗县| 江山市| 延吉市| 普宁市| 北海市| 肥城市| 贵溪市| 招远市| 肇庆市| 杂多县| 阳城县| 东阳市| 孝义市| 富蕴县| 门源|