Golang——9、反射和文件操作

反射和文件操作

  • 1、反射
    • 1.1、reflect.TypeOf()獲取任意值的類型對象
    • 1.2、reflect.ValueOf()
    • 1.3、結構體反射
  • 2、文件操作
    • 2.1、os.Open()打開文件
    • 2.2、方式一:使用Read()讀取文件
    • 2.3、方式二:bufio讀取文件
    • 2.4、方式三:os.ReadFile讀取
    • 2.5、寫入文件
    • 2.6、復制文件
    • 2.7、文件重命名
    • 2.8、創建目錄
    • 2.9、刪除目錄和文件

1、反射

有時我們需要寫一個函數,這個函數有能力統一處理各種值類型,而這些類型可能無法共享同一個接口, 也可能布局未知,也有可能這個類型在我們設計函數時還不存在,這個時候我們就可以用到反射。

空接口可以存儲任意類型的變量,那我們如何知道這個空接口保存數據的類型是什么?值是什么呢?
1、可以使用類型斷言
2、可以使用反射實現, 也就是在程序運行時動態的獲取一個變量的類型信息和值信息。

Golang 中反射可以實現以下功能:
1、反射可以在程序運行期間動態的獲取變量的各種信息,比如變量的類型、類別
2、如果是結構體,通過反射還可以獲取結構體本身的信息,比如結構體的字段、結構體的方法、結構體的tag。
3、通過反射,可以修改變量的值,可以調用關聯的方法。
Go 語言中的變量是分為兩部分的:
? 類型信息:預先定義好的元信息。
? 值信息:程序運行過程中可動態變化的。
在GoLang的反射機制中,任何接口值都由是一個具體類型和具體類型的值兩部分組成的。在GoLang中,反射的相關功能由內置的reflect包提供,任意接口值在反射中都可以理解為由reflect.Type和reflect.Value兩部分組成,并且reflect包提供了reflect.TypeOf和reflect.ValueOf兩個重要函數來獲取任意對象的Value和Type。

1.1、reflect.TypeOf()獲取任意值的類型對象

1、使用reflect.TypeOf可以獲取函數類型對象。

package mainimport ("fmt""reflect"
)type myInt inttype Person struct {Name stringAge  int
}// 通過反射獲取任意變量的類型
func reflectFn(x interface{}) {v := reflect.TypeOf(x)fmt.Println(v)
}func main() {reflectFn(10)var a = 10reflectFn(3.1415)reflectFn(true)reflectFn("你好golang")reflectFn([]int{1, 2, 3, 4, 5})reflectFn(&a)p := Person{Name: "張三",Age:  18,}reflectFn(p)var x myInt = 10reflectFn(x)
}

在這里插入圖片描述

2、通過reflect.TypeOf獲取返回的類型對象后,該對象里面還有兩個方法Name和Kind。Name用來獲取類型名稱,Kind用來獲取類型種類。

package mainimport ("fmt""reflect"
)type myInt inttype Person struct {Name stringAge  int
}func reflectFn(x interface{}) {v := reflect.TypeOf(x)fmt.Printf("類型: %v, 類型名稱: %v, 類型種類: %v\n", v, v.Name(), v.Kind())
}func main() {var a = 10reflectFn(10)reflectFn(3.1415)reflectFn(true)reflectFn("你好golang")reflectFn([]int{1, 2, 3, 4, 5})reflectFn(&a)p := Person{Name: "張三",Age:  18,}reflectFn(p)var x myInt = 10reflectFn(x)
}

在這里插入圖片描述

Go語言的反射中像數組、切片、Map、指針等類型的變量,它們的.Name()都是返回空。種類(Kind)就是指底層的類型。


1.2、reflect.ValueOf()

reflect.ValueOf()返回的是 reflect.Value 類型,其中包含了原始值的值信息。reflect.Value 與原始值之間可以互相轉換。
在這里插入圖片描述

1、例如實現接受任意值的接口,提取出原始值進行運算操作。

package mainimport ("fmt""reflect"
)func reflectFn(x interface{}) {v := reflect.ValueOf(x)num := v.Int() + 10fmt.Println(num)
}func main() {reflectFn(10)
}

在這里插入圖片描述
在上面的代碼中,我們先獲取reflec.Value對象,然后通過該對象獲取原始值進行運算操作。

2、但是上面這種情況是在我們知道類型的情況下,調用對應的獲取原始值方法, 如果有多種類型,我們就需要進行判斷。我們可以使用reflec.Value對象提供的kind函數獲取種類,然后根據種類進行判斷再調用對應的獲取原始值方法。

package mainimport ("fmt""reflect"
)func reflectFn(x interface{}) {v := reflect.ValueOf(x)kind := v.Kind()switch kind {case reflect.Int:fmt.Printf("int類型的原始值: %v\n", v.Int())case reflect.Bool:fmt.Printf("bool類型的原始值: %v\n", v.Bool())case reflect.Float64:fmt.Printf("float64類型的原始值: %v\n", v.Float())case reflect.String:fmt.Printf("string類型的原始值: %v\n", v.String())default:fmt.Println("還沒有判斷這個類型...")}
}func main() {reflectFn(10)reflectFn(true)reflectFn(3.1415)reflectFn("你好golang")
}

在這里插入圖片描述

3、在反射中修改變量的值。
想要在函數中通過反射修改變量的值, 需要注意函數參數傳遞的是值拷貝, 必須傳遞變量地址才能修改變量值。而反射中使用專有的 Elem()方法來獲取指針對應的值。

package mainimport ("fmt""reflect"
)func reflectFn(x interface{}) {v := reflect.ValueOf(x)fmt.Println(v, v.Kind(), v.Elem(), v.Elem().Kind())
}func main() {var x = 10reflectFn(&x)
}

在這里插入圖片描述
由于我們傳入的是一個指針,所以獲取值對象打印輸出就是一個地址,通過kind獲取類型是ptr,我們可以通過Elem函數來獲取該指針指向的值,而不能通過解引用的方式來直接獲取。要修改對應的值就先使用.Elem獲取對象,然后再調用SetXXX來修改。

package mainimport ("fmt""reflect"
)func reflectFn(x interface{}) {v := reflect.ValueOf(x)if v.Elem().Kind() == reflect.Int {v.Elem().SetInt(20)} else if v.Elem().Kind() == reflect.String {v.Elem().SetString("hello c++")}
}func main() {var x = 10var str = "hello golang"fmt.Println(x, str)reflectFn(&x)reflectFn(&str)fmt.Println(x, str)
}

在這里插入圖片描述


1.3、結構體反射

任意值通過reflect.TypeOf()獲得反射對象信息后,如果它的類型是結構體,可以通過反射值對象(reflect.Type)的NumField()和Field()方法獲得結構體成員的詳細信息。
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

1、通過類型變量的Field方法獲取結構體字段。

package mainimport ("fmt""reflect"
)type Student struct {Name  string `json:"name1" form:"uername"`Age   int    `json:"age"`Score int    `json:"score"`
}func (s Student) GetInfo() {fmt.Printf("姓名: %v, 年齡: %v, 成績: %v\n", s.Name, s.Age, s.Score)
}func (s *Student) SetInfo(name string, age int, score int) {s.Name = names.Age = ages.Score = score
}func PrintStructField(s Student) {t := reflect.TypeOf(s)// v := reflect.ValueOf(s)if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {fmt.Println("傳入的不是一個結構體類型...")return}// 1.通過類型變量的Field方法獲取結構體字段field0 := t.Field(0)fmt.Printf("%#v\n", field0)
}func main() {stu := Student{Name:  "張三",Age:   18,Score: 99,}PrintStructField(stu)
}

返回的是一個reflect.StructField對象,我們打印出看看里面有什么內容。
在這里插入圖片描述
我們可以通過該結構體對象的Name、Type、Tag方法來獲取對應的信息:

field0 := t.Field(0)
fmt.Printf("%#v\n", field0)
fmt.Println("字段名稱:", field0.Name)
fmt.Println("字段類型:", field0.Type)
fmt.Println("字段Tag:", field0.Tag.Get("json"))
fmt.Println("字段Tag:", field0.Tag.Get("form"))

在這里插入圖片描述

2、通過類型變量的FieldByName方法可以獲取結構體字段。

field1, _ := t.FieldByName("Age")
fmt.Println("字段名稱:", field1.Name)
fmt.Println("字段類型:", field1.Type)
fmt.Println("字段Tag:", field1.Tag.Get("json"))

在這里插入圖片描述

3、通過類型變量的NumField方法可以獲取到該結構體里有幾個字段。

var fieldCount = t.NumField()
fmt.Println("該結構體字段數量:", fieldCount)

4、通過值變量獲取結構體里面對應的值。

v := reflect.ValueOf(s)
fmt.Printf("Name的值: %v, Age的值: %v\n", v.Field(0), v.FieldByName("Age"))

5、通過類型變量里面的Method方法獲取結構體中的方法。

func PrintStructFn(x interface{}) {t := reflect.TypeOf(x)if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {fmt.Println("傳入的參數不是一個結構體...")return}method0 := t.Method(0)fmt.Println("方法名稱:", method0.Name)fmt.Println("方法類型:", method0.Type)
}

在這里插入圖片描述
這里傳入0獲取方法并不是按照方法的定義順序來獲取的,而是通過字典序來獲取的。

6、通過類型變量里面的MethodByName獲取方法。

method1, _ := t.MethodByName("GetInfo")
fmt.Println("方法名稱:", method1.Name)
fmt.Println("方法類型:", method1.Type)

也可以通過NumMethod獲取該結構體中有多少個方法。

7、通過值變量來執行方法。

v := reflect.ValueOf(x)
v.MethodByName("GetInfo").Call(nil)

上面調用GetInfo方法不需要傳參,Call里面填寫nil即可,如果需要傳參需要定義一個reflect.Value切片傳入,如下:

fmt.Println(x)
var params []reflect.Value
params = append(params, reflect.ValueOf("李四"))
params = append(params, reflect.ValueOf(22))
params = append(params, reflect.ValueOf(100))
v.MethodByName("SetInfo").Call(params)
fmt.Println(x)

在這里插入圖片描述

8、反射修改結構體屬性。

package mainimport ("fmt""reflect"
)type Student struct {Name  string `json:"name"`Age   int    `json:"age"`Score int    `json:"score"`
}func reflectChange(x interface{}) {t := reflect.TypeOf(x)v := reflect.ValueOf(x)if t.Kind() != reflect.Ptr {fmt.Println("傳入的不是指針類型...")}if t.Elem().Kind() != reflect.Struct {fmt.Println("傳入的不是結構體指針類型...")}name := v.Elem().FieldByName("Name")name.SetString("李四")age := v.Elem().FieldByName("Age")age.SetInt(22)
}func main() {stu := Student{Name:  "張三",Age:   18,Score: 100,}fmt.Println(stu)reflectChange(&stu)fmt.Println(stu)
}

在這里插入圖片描述


2、文件操作

2.1、os.Open()打開文件

打開文件使用os.Open函數,傳入文件的地址,可以采用絕對地址也可以采用相對地址。記得調用Close函數關閉文件。

package mainimport ("fmt""os"
)func main() {file, err := os.Open("./main.go")defer file.Close()if err != nil {fmt.Println("err:", err)return}
}

這種打開方式默認是只讀的。


2.2、方式一:使用Read()讀取文件

在這里插入圖片描述

調用Read函數需要傳入一個byte切片類型用來存儲數據。該函數有兩個返回值,第一個返回值表示讀取的字節數。

package mainimport ("fmt""io""os"
)func main() {file, err := os.Open("./main.go")defer file.Close()if err != nil {fmt.Println("err:", err)return}var str []bytetmp := make([]byte, 128)for {n, err := file.Read(tmp)if err == io.EOF {fmt.Println("讀取完畢...")break}if err != nil {fmt.Println("err:", err)return}str = append(str, tmp[:n]...)}fmt.Println(string(str))
}

注意:
1、每次只能讀取128個字節,所以我們不知道什么時候讀取完畢,通過對err == io.EOF來判斷是否讀取完畢。
2、切片是飲用類型,我們在拼接兩個切片的時候要指明tmp的區間,否則可能會把之前殘留的數據也拼接到str中。


2.3、方式二:bufio讀取文件

package mainimport ("bufio""fmt""io""os"
)func main() {file, err := os.Open("./main.go")defer file.Close()if err != nil {fmt.Println(err)return}var fileStr stringreader := bufio.NewReader(file)for {str, err := reader.ReadString('\n') // 表示一次讀取一行if err == io.EOF {fileStr += strbreak}if err != nil {fmt.Println(err)return}fileStr += str}fmt.Println(fileStr)
}

2.4、方式三:os.ReadFile讀取

package mainimport ("fmt""os"
)func main() {byteStr, err := os.ReadFile("./main.go")if err != nil {fmt.Println(err)return}fmt.Println(string(byteStr))
}

2.5、寫入文件

寫入文件就不能使用os.Open()打開了,這樣是只讀的,需要使用os.OpenFile()函數。

func OpenFile(name string, flag int, perm FileMode) (*File, error) {
...
}

name:要打開的文件名。flag:打開文件的模式。模式有以下幾種:
在這里插入圖片描述
perm表示文件的權限,如果文件不存在我們創建文件的權限,傳入0666即可。

下面演示三種寫入文件的方式:
1、Write和WriteString寫入。

package mainimport ("fmt""os"
)func main() {file, err := os.OpenFile("./file.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)defer file.Close()if err != nil {fmt.Println(err)return}for i := 0; i < 10; i++ {file.WriteString(fmt.Sprintf("我是一行字符串-%d\n", i))}var str = "哈哈哈哈哈"file.Write([]byte(str))
}

2、bufio.NewWriter配合Flush寫入。

package mainimport ("bufio""fmt""os"
)func main() {file, err := os.OpenFile("./file.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)defer file.Close()if err != nil {fmt.Println(err)}writer := bufio.NewWriter(file)for i := 1; i <= 10; i++ {writer.WriteString(fmt.Sprintf("我是一行字符串-%d\n", i))}writer.Flush()
}

這里寫入的是緩存中,我們還需要調用Flush刷新才行。

3、os.WriteFile寫入。

package mainimport ("fmt""os"
)func main() {str := "hello world"err := os.WriteFile("./file.txt", []byte(str), 0666)if err != nil {fmt.Println(err)}
}

注意,這種寫入的方式每次都會清空文件內容,所以如果要追加寫入還是得采用前兩種方式。


2.6、復制文件

實現方式一,通過os.ReadFile從文件中讀取所有內容,再通過os.WriteFile寫入到另一個文件中。

package mainimport ("fmt""os"
)func copy(srcFileName string, dstFileName string) error {byteStr, err := os.ReadFile(srcFileName)if err != nil {return err}err = os.WriteFile(dstFileName, byteStr, 0666)if err != nil {return err}return nil
}func main() {src := "./file1.txt"dst := "./file2.txt"err := copy(src, dst)if err != nil {fmt.Println(err)return}fmt.Println("復制文件成功")
}

方式二:方法流的方式復制。

package mainimport ("fmt""io""os"
)func copy(srcFileName string, dstFileName string) error {src, err := os.Open(srcFileName)defer src.Close()if err != nil {return err}dst, err := os.OpenFile(dstFileName, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)defer dst.Close()if err != nil {return err}var byteStr = make([]byte, 128)for {n, err := src.Read(byteStr)if err == io.EOF {break}if err != nil {return err}if _, err := dst.Write(byteStr[:n]); err != nil {return err}}return nil
}func main() {src := "./file1.txt"dst := "./file2.txt"err := copy(src, dst)if err != nil {fmt.Println(err)}fmt.Println("復制文件完成...")
}

2.7、文件重命名

使用os.Rename函數對文件進行重命名。

package mainimport ("fmt""os"
)func main() {err := os.Rename("./file1.txt", "./file2.txt")if err != nil {fmt.Println(err)return}fmt.Println("重命名成功...")
}

2.8、創建目錄

使用os.Mkdir創建目錄,使用os.MkdirAll創建多級目錄。

package mainimport ("fmt""os"
)func main() {err := os.Mkdir("./abc", 0666)if err != nil {fmt.Println(err)return}fmt.Println("創建目錄成功...")err = os.MkdirAll("./d1/d2/d3", 0666)if err != nil {fmt.Println(err)return}fmt.Println("創建多級目錄成功...")
}

2.9、刪除目錄和文件

使用os.Remove刪除目錄或文件,使用os.RemoveAll刪除多個文件或目錄。

package mainimport ("fmt""os"
)func main() {err := os.Remove("./file1.txt")if err != nil {fmt.Println(err)return}err = os.Remove("./d1")if err != nil {fmt.Println(err)return}err = os.RemoveAll("./d2")if err != nil {fmt.Println(err)return}fmt.Println("刪除成功...")
}

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

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

相關文章

[閉源saas選項]Pinecone:為向量數據庫而生的實時語義搜索引擎

目錄 Pinecone&#xff1a;為向量數據庫而生的實時語義搜索引擎 一、什么是 Pinecone&#xff1f; 二、Pinecone 是開源的嗎&#xff1f;支持私有化部署嗎&#xff1f; 三、為什么需要向量搜索&#xff1f; 四、Pinecone 的核心優勢 五、使用 Pinecone 的典型流程 六、在…

【Maniskill】使用Ppo的官方基線訓練時出現指標突然“塌陷”的現象

1. 問題描述 1.1 在使用官方代碼進行訓練的時候“success_once突然掉落到0” 簡要說明你在使用官方 examples/baselines/ppo/baselines.sh 腳本訓練 PickCube-v1 時&#xff0c;在 early stage&#xff08;如前 50 k 步&#xff09;指標正常、success_once 接近 1&#xff0c;…

本地部署大模型實戰:使用AIStarter一鍵安裝Ollama+OpenWeb教程(含最新版本更新指南)

大家好&#xff01;今天給大家帶來一個本地部署大模型的詳細教程 &#xff0c;主要介紹如何通過 AIStarter 4.0 一鍵部署 Ollama OpenWeb 的完整流程。如果你還在為在線大模型不穩定、隱私泄露等問題煩惱&#xff0c;那么本地部署 將是一個非常不錯的選擇&#xff01; 首先&am…

Redis大量key集中過期怎么辦

當 Redis 中存在大量 key 在同一時間點集中過期時&#xff0c;可能會導致以下問題&#xff1a; 請求延遲增加&#xff1a;Redis 在處理過期 key 時需要消耗 CPU 資源&#xff0c;如果過期 key 數量龐大&#xff0c;會導致 Redis 實例的 CPU 占用率升高&#xff0c;進而影響其他…

【Linux 學習計劃】-- 系統中進程是如何調度的(內核進程調度隊列)

目錄 回顧進程優先級與進程調度的引入 內核runqueue圖例 關于queue[140]前100個位置 | 實時進程與分時進程 遍歷需要調度的進程與bitmap的引入 active、expired指針 結語 回顧進程優先級與進程調度的引入 在我們之前的學習中&#xff0c;我們是有學習過進程優先級這個概…

【Spring AI 1.0.0】Spring AI 1.0.0框架快速入門(1)——Chat Client API

Spring AI框架快速入門 一、前言二、前期準備2.1 運行環境2.2 maven配置2.3 api-key申請 三、Chat Client API3.1 導入pom依賴3.2 配置application.properties文件3.3 創建 ChatClient3.3.1 使用自動配置的 ChatClient.Builder3.3.2 使用多個聊天模型 3.4 ChatClient請求3.5 Ch…

微信小程序開發一個自定義組件的詳細教程

以下是一個微信小程序自定義組件的詳細教程&#xff0c;覆蓋開發文檔中的核心知識點。我們將以一個包含屬性、事件、插槽、生命周期等功能的按鈕組件為例進行說明&#xff1a; 一、創建組件 在 components 目錄下新建 custom-button 文件夾&#xff0c;包含以下文件&#xff…

模電——第四講場效應管

定義&#xff1a;具有正向受控作用的半導體器件 分類&#xff1a;MOS&#xff08;絕緣柵&#xff09;場效應管和結性場效應管 區別&#xff1a;場效應管相比于晶體管&#xff0c;輸入電阻很大&#xff0c;是單極型器件 MOS場效應管&#xff1a; 特性曲線 利用半導體表面的電…

[藍橋杯]堆的計數

堆的計數 題目描述 我們知道包含 NN 個元素的堆可以看成是一棵包含 NN 個節點的完全二叉樹。 每個節點有一個權值。對于小根堆來說&#xff0c;父節點的權值一定小于其子節點的權值。 假設 NN 個節點的權值分別是 1~NN&#xff0c;你能求出一共有多少種不同的小根堆嗎&…

論文閱讀:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻譯 自動駕駛技術作為推動交通和城市出行變革的催化劑&#xff0c;正從基于規則的系統向數據驅動策略轉變。傳統的模塊化系統受限于級聯模塊間的累積誤差和缺乏靈活性的預設規則。…

WebRTC中的幾個Rtp*Sender

一、問題&#xff1a; webrtc當中有幾個比較相似的類&#xff0c;看著都是發送RTP數據包的&#xff0c;分別是&#xff1a;RtpPacketToSend 和RtpSenderVideo還有RtpVideoSender以及RTPSender&#xff0c;這說明什么呢&#xff1f;首先&#xff0c;說明我會很多連詞&#xff0…

EFI(x64)簡易開發環境

文章目錄 1 必須文件2 運行環境3 構建應用 (Visual Studio)4 引用 EDK2 頭文件 1 必須文件 EDK2: 可以只拉取倉庫本身, 不拉取其子倉庫(完整構建才需要) qemu: qemu 以源碼發布, QEMU for Windows – Installers (64 bit) 這里有民間構建的安裝包 2 運行環境 創建一個 root …

八皇后問題深度解析

八皇后問題深度解析 一、八皇后問題的起源與背景1.1 問題起源1.2 歷史發展 二、問題描述與約束條件2.1 問題描述2.2 約束條件 三、算法原理&#xff1a;回溯算法3.1 回溯算法概述3.2 八皇后問題的回溯算法實現思路 四、八皇后問題的多語言實現4.1 Python實現4.2 C實現4.3 Java實…

Cursor 工具項目構建指南: Python 3.8 環境下的 Prompt Rules 約束

簡簡單單 Online zuozuo: 簡簡單單 Online zuozuo 簡簡單單 Online zuozuo 簡簡單單 Online zuozuo 簡簡單單 Online zuozuo :本心、輸入輸出、結果 簡簡單單 Online zuozuo : 文章目錄 Cursor 工具項目構建指南: Python 3.8 環境下的 Prompt Rules 約束前言項目簡介技術棧…

Java中的阻塞隊列

阻塞隊列是什么&#xff1f; 一、阻塞隊列的核心概念與特性 1.1 阻塞隊列是什么&#xff1f; 簡單來說&#xff0c;阻塞隊列是一種特殊的隊列&#xff0c;它具備普通隊列先進先出&#xff08;FIFO&#xff09;的特性&#xff0c;同時還支持兩個額外的重要操作&#xff1a; 當…

v1.0.1版本更新·2025年5月22日發布-優雅草星云物聯網AI智控系統

v1.0.1版本更新2025年5月22日發布-優雅草星云物聯網AI智控系統 開源地址 星云智控官網&#xff1a; 優雅草星云物聯網AI智控軟件-移動端vue: 優雅草星云物聯網AI智控軟件-移動端vue 星云智控PC端開源&#xff1a; 優雅草星云物聯網AI智控軟件-PC端vue: 優雅草星云物聯網AI…

Java-IO流之轉換流詳解

Java-IO流之轉換流詳解 一、轉換流概述1.1 什么是轉換流1.2 轉換流的作用1.3 轉換流的位置 二、InputStreamReader詳解2.1 基本概念2.2 構造函數2.3 核心方法2.4 使用示例&#xff1a;讀取不同編碼的文件 三、OutputStreamWriter詳解3.1 基本概念3.2 構造函數3.3 核心方法3.4 使…

android lifeCycleOwner生命周期

一 Fragment中 viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) 什么時候執行&#xff1f; 讓我分析一下相關問題&#xff1a; 關于 onPause 時的數據更新: viewLifecycleOwner.lifecycleScope.launch {viewLifecycleOwner.repeatOnLifecycle(Lifecycle.Sta…

Liunx進程替換

文章目錄 1.進程替換2.替換過程3.替換函數exec3.1命名解釋 4.細說6個exe函數execl函數execvexeclp、execvpexecle、execve 1.進程替換 fork&#xff08;&#xff09;函數在創建子進程后&#xff0c;子進程如果想要執行一個新的程序&#xff0c;就可以使用進程的程序替換來完成…

【華為云Astro-服務編排】服務編排中圖元的使用與配置

目錄 子服務編排圖元 子服務編排圖元的作用 如何使用子服務編排圖元 腳本圖元 腳本圖元的作用 如何使用腳本圖元 記錄創建圖元 記錄創建圖元的作用 如何使用記錄創建圖元 記錄刪除圖元 記錄刪除圖元的作用 如何使用記錄刪除圖元 記錄查詢圖元 記錄查詢圖元的作用…