Go反射程式設計

2021-10-06 16:15:41 字數 4412 閱讀 8038

reflect.typeof vs. reflect.valueof:

func

checktype

(v inte***ce)}

func

testbasictype

(t *testing.t)

利用反射編寫靈活的**:

type employee struct

func

(e *employee)

updateage

(newval int

)func

testinvokebyname

(t *testing.t)

// 按名字獲取成員

t.logf

("name:value(%[1]v),type(%[1]t)"

, reflect.

valueof

(*e)

.fieldbyname

("name"))

if namefield, ok := reflect.

typeof

(*e)

.fieldbyname

("name");

!ok

else

reflect.

valueof

(e).

methodbyname

("updateage").

call([

]reflect.value

) t.

log(

"updated age:"

, e)

/** 執行結果:

=== run testinvokebyname

testinvokebyname: reflect_test.go:28: name:value(mike),type(reflect.value)

testinvokebyname: reflect_test.go:32: tag:format normal

testinvokebyname: reflect_test.go:35: updated age: &

--- pass: testinvokebyname (0.00s)

*/}

struct tag:

type basicinfo struct

訪問struct:

if namefield, ok := reflect.

typeof

(*e)

.fieldbyname

("name");

!ok

else

reflect.type 和 reflflect.value 都有 fieldbyname ⽅法,注意他們的區別。

deepequal:

比較切片和map

type customer struct

func

testdeepequal

(t *testing.t)

b :=

map[

int]

string

fmt.

println

(reflect.

deepequal

(a, b)

) s1 :=

int s2 :=

int s3 :=

int t.

log(

"s1 == s2?"

, reflect.

deepequal

(s1, s2)

) t.

log(

"s1 == s3?"

, reflect.

deepequal

(s1, s3)

) c1 := customer

c2 := customer

fmt.

println

(reflect.

deepequal

(c1, c2)

)/** 執行結果:

=== run testdeepequal

false

testdeepequal: fiexible_reflect_test.go:23: s1 == s2? true

testdeepequal: fiexible_reflect_test.go:24: s1 == s3? false

true

--- pass: testdeepequal (0.00s)

*/}

關於「反射」你應該知道的:

type employee struct

func

(e *employee)

updateage

(newval int

)type customer struct

func

fillbysettings

(st inte***ce

, settings map

[string

]inte***ce

)error

// elem() 獲取指標指向的值

if reflect.

typeof

(st)

.elem()

.kind()

!= reflect.struct

if settings ==

nilvar

( field reflect.structfield

ok bool

)for k, v :=

range settings

if field.type == reflect.

typeof

(v)}

return

nil}

func

testfillnameandage

(t *testing.t)

e := employee

if err :=

fillbysettings

(&e, settings)

; err !=

nil t.

log(e)

c :=

new(customer)

if err :=

fillbysettings

(c, settings)

; err !=

nil t.

log(

*c)/** 執行結果:

=== run testfillnameandage

testfillnameandage: fiexible_reflect_test.go:69:

testfillnameandage: fiexible_reflect_test.go:74:

--- pass: testfillnameandage (0.00s)

*/}

」不安全「行為的危險性:

func

testunsafe

(t *testing.t)

// the cases is suitable for unsafe

type myint int

// 合理的型別轉換

func

testconvert

(t *testing.t)

b :=*(

*[]myint)

(unsafe.

pointer

(&a)

) t.

log(b)

/** 執行結果:

=== run testconvert

testconvert: unsafe_test.go:26: [1 2 3 4]

--- pass: testconvert (0.00s)

*/}// 原子型別操作

func

testatomic

(t *testing.t)

for i :=

0; i <

100; i++

atomic.

storepointer

(&sharebuffer, unsafe.

pointer

(&data))}

readdatafn :=

func()

var wg sync.waitgroup

writedatafn()

for i :=

0; i <

10; i++

wg.done()

}() wg.

add(1)

gofunc()

wg.done()

}()}

wg.wait()

}

go 反射應用

直接上 package main import fmt reflect type envkey struct func main 反射 s reflect.valueof t elem typeoft s.type 迴圈遍歷結構體,獲取各個元素的型別,值 for i 0 i s.numfield i...

Go語言反射

反射是指在程式執行過程中對程式本身進行訪問和修改的能力。程式在編譯時,變數被轉換為記憶體位址,變數名不會被編譯器寫入到可執行部分。在執行程式時,程式無法獲取自身資訊。支援反射的語言可以在程式編譯期將變數的反射資訊,如欄位名稱 型別資訊 結構體資訊等整合到可執行檔案中,並給程式提供介面的訪問反射資訊,...

go 反射應用

package main import fmt encoding json type monster struct func main data,json.marshal m fmt.println json result string data 輸出結果 json result 思考問題 為什麼序...