golang反射 二 反射結構體切片讀取資料

2021-10-12 02:49:47 字數 3160 閱讀 2032

type man struct

s1 :=

make([

]man,0)

s1 =

(s1, man

)s1 =

(s1, man

)s1 =

(s1, man

)func

(v inte***ce

) l := getvalue.

len(

)for i :=

0; i < l; i++

fmt.

printf

("type-kind: %s, type-name: %s, value: %v\n"

, typel.

kind()

, typel.

name()

, value.

inte***ce()

) num := value.

numfield()

for j :=

0; j < num; j++

fmt.

println()

}}(s1)

列印資訊

type-kind: struct, type-name: man, value: 

name: id, type: int, value: 1

name: name, type: string, value: a

type-kind: struct, type-name: man, value:

name: id, type: int, value: 2

name: name, type: string, value: b

type-kind: struct, type-name: man, value:

name: id, type: int, value: 3

name: name, type: string, value: c

根據示例:

通過 reflect.valueof(v) 得到 v 的 value 物件,它的 len() 方法可以得到切片的長度;

通過 value 物件的 index(i) 方法得到第 i 的元素 value 物件,然後通過 value 物件得到 type 物件;

後面的就是反射結構體的套路了。

index 方法可以適用於 array, slice, or string

len 方法可以適用於 array, chan, map, slice, or string

// len returns v's length.

// it panics if v's kind is not array, chan, map, slice, or string.

func

(v value)

len(

)int

panic

(&valueerror)}

// index returns v's i'th element.

// it panics if v's kind is not array, slice, or string or i is out of range.

func

(v value)

index

(i int

) value

typ := tt.elem

offset :=

uintptr

(i)* typ.size

// either flagindir is set and v.ptr points at array,

// or flagindir is not set and v.ptr is the actual array data.

// in the former case, we want v.ptr + offset.

// in the latter case, we must be doing index(0), so offset = 0,

// so v.ptr + offset is still the correct address.

val :=

add(v.ptr, offset,

"same as &v[i], i < tt.len"

) fl := v.flag&

(flagindir|flagaddr)

| v.flag.ro(

)|flag

(typ.

kind()

)// bits same as overall array

return value

case slice:

// element flag same as elem of ptr.

// addressable, indirect, possibly read-only.

s :=

(*sliceheader)

(v.ptr)

ifuint

(i)>=

uint

(s.len)

tt :=

(*slicetype)

(unsafe.

pointer

(v.typ)

) typ := tt.elem

val :=

arrayat

(s.data, i, typ.size,

"i < s.len"

) fl := flagaddr | flagindir | v.flag.ro(

)|flag

(typ.

kind()

)return value

case string:

s :=

(*stringheader)

(v.ptr)

ifuint

(i)>=

uint

(s.len)

p :=

arrayat

(s.data, i,1,

"i < s.len"

) fl := v.flag.ro(

)|flag

(uint8)

| flagindir

return value

}panic

(&valueerror

)}

golang反射還原結構體中的字段

假設有這樣乙個結構體 type s struct a s 3.14 用反射可以輕鬆拿到每個欄位的值 reflect.valueof a fieldbyname a reflect.valueof a fieldbyname b reflect.valueof a fieldbyname c 但這樣返...

golang 利用反射機制對結構體進行迴圈賦值

熟悉c語言的朋友都知道,c語言的指標操作某些方面是很方便的。如假設你知道記憶體中有乙個連續100個位元組的區域,或者你有乙個連續100個位元組的位元組陣列,你需要用其對乙個已經定義好的結構體進行賦值,在c語言你可以簡單地將記憶體資料中的頭位址,或者位元組陣列的頭位址賦值給結構體指標就行。但在go語言...

golang通過反射設定結構體變數的值

如果需要動態設定struct變數field的情況下,可以利用reflect來完成。package main import fmt reflect 定義結構體person type person struct func main fmt.prin程式設計客棧tln person 修改前 pp refl...