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...