Golang 利用反射修改不同型別物件的值

2021-10-22 21:26:01 字數 2900 閱讀 4746

在寫**時,我們可能會有這樣的需求:根據特定的物件型別進行定製操作

針對這件事情,c++中提供了type_traits這一機制。說的高大上一些,它是一種萃取機。實際上我認為type_traits就是利用模板的特化和模板引數推導,從而在編譯期就獲得的類模板的乙個例項。

而接下來介紹go一種比較有意思的機制:反射。相當特別的是,這件事是在執行期完成的。

借用李文周的部落格中對反射的介紹:

反射是指在程式執行期對程式本身進行訪問和修改的能力。程式在編譯時,變數被轉換為記憶體位址,變數名不會被編譯器寫入到可執行部分。在執行程式時,程式無法獲取自身的資訊。

支援反射的語言可以在程式編譯期將變數的反射資訊,如欄位名稱、型別資訊、結構體資訊等整合到可執行檔案中,並給程式提供介面訪問反射資訊,這樣就可以在程式執行期獲取型別的反射資訊,並且有能力修改它們。

可以看到,反射在為程式設計師提供便利時也帶來了一些執行期的開銷,這一點可能比較像c++中的rtti技術。同樣的,過多的反射會降低可執行程式的執行效率,我們應該慎用它

這裡只舉了string和int的例子,具體講解在注釋中。

package main

import

("fmt"

"reflect"

)// typeof : 型別資訊

// valueof : 值資訊

func

set_val

(src inte***ce

, dst inte***ce

)bool

// 到此處應是乙個有效的ptr

src_elem := src_val.

elem()

switch src_elem.

kind()

return

true

}// 修改反射物件

func

main()

輸出:

0 s

can't set int

can't set string

0 sstring

: alter s in func set_val

int:

666 in func set_val

666 alter s

另外,當我嘗試修改結構體成員時,我失敗了,我找不到乙個通用的方法使reflect.value轉換成實際型別。並且我發現傳入乙個reflect.value型別時會出現不正確的結果(在例子中,物件被識別為struct),而在**中呼叫kind,顯示又是正確的。這樣的話可能就沒法遞迴呼叫這個函式了。

**如下:

package main

import

("fmt"

"reflect"

)type s struct

// typeof : 型別資訊

// valueof : 值資訊

func

set_val

(src inte***ce

, dst inte***ce

)bool

// 到此處應是乙個有效的ptr

src_elem := src_val.

elem()

// 獲取結構體成員

// 對非ptr呼叫elem會造成panic

var dst_elem reflect.value

if dst_val.

kind()

== reflect.ptr

else

switch src_elem.

kind()

fmt.

printf

("struct : %v in func set_val\n"

, src_elem)

default

: fmt.

printf

("unknow type : in func set_val\n")}

return

true

}// 修改反射物件

func

main()

) fmt.

println

(i, s, s_struct)

// 無效的修改

set_val

(i,666

)set_val

(s,"alter s"

) fmt.

println

(i, s, s_struct)

// 有效的修改

set_val

(&s,

"alter s"

)set_val

(&i,

666)

set_val

(&s_struct, s

) fmt.

println

(i, s, s_struct)

}

輸出:

0 s 

can't set int

can't set string

0 s

string

: alter s in func set_val

int:

666 in func set_val

can't set struct

can't set struct

struct

: in func set_val

666 alter s

go語言基礎之反射 | 李文周的部落格

golang reflect - go語言中文網 - golang中文社群

不同型別的檔案

cpp檔案 cpp是用c 語言編寫的源 檔案的字尾 具體實現 h檔案 h是c語言和c 語言的標頭檔案 函式宣告,巨集定義,函式原型 pde檔案 一共有4種可能,分別為 1 powerdesk encrypted file 2 pathology data exchange file 3 afp pa...

C 不同型別的畫筆!

畫筆是可以與graphics物件一起用來建立實心形狀和呈現文字的物件。1.solidbrush 畫筆最簡單形式,用純色進行繪製。2.hatchbrush 類似與 1 但它可以選擇大量預設圖案,而不是純色。要命名空間 using system.drawing.drawing2d 3.texturebr...

不同型別Trigger的選擇

1.trigger 一般用於實現每隔一定時間執行任務,以及重複多少次,如每 60 秒執行一次,重複執行 6 次。問題 1 在使用過程中發現設定執行6次其實是執行7次,有一次是在開始執行的第 0 秒執行了一次,然後根據執行間隔再執行給定的執行次數。2 當有 misfired 的任務並且恢復執行時,該執...