reflect: add valueFlagRO
Этот коммит содержится в:
родитель
5faff2e13a
коммит
0cd93a3a9e
1 изменённых файлов: 37 добавлений и 8 удалений
|
@ -14,6 +14,10 @@ type valueFlags uint8
|
||||||
const (
|
const (
|
||||||
valueFlagIndirect valueFlags = 1 << iota
|
valueFlagIndirect valueFlags = 1 << iota
|
||||||
valueFlagExported
|
valueFlagExported
|
||||||
|
valueFlagEmbedRO
|
||||||
|
valueFlagStickyRO
|
||||||
|
|
||||||
|
valueFlagRO = valueFlagEmbedRO | valueFlagStickyRO
|
||||||
)
|
)
|
||||||
|
|
||||||
type Value struct {
|
type Value struct {
|
||||||
|
@ -36,6 +40,16 @@ func (v Value) isExported() bool {
|
||||||
return v.flags&valueFlagExported != 0
|
return v.flags&valueFlagExported != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) isRO() bool {
|
||||||
|
return v.flags&(valueFlagRO) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Value) checkRO() {
|
||||||
|
if v.isRO() {
|
||||||
|
panic("reflect: value is not settable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Indirect(v Value) Value {
|
func Indirect(v Value) Value {
|
||||||
if v.Kind() != Ptr {
|
if v.Kind() != Ptr {
|
||||||
return v
|
return v
|
||||||
|
@ -210,7 +224,7 @@ func (v Value) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) CanInterface() bool {
|
func (v Value) CanInterface() bool {
|
||||||
return v.isExported()
|
return v.isExported() && !v.isRO()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) CanAddr() bool {
|
func (v Value) CanAddr() bool {
|
||||||
|
@ -268,7 +282,7 @@ func (v Value) UnsafeAddr() uintptr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) CanSet() bool {
|
func (v Value) CanSet() bool {
|
||||||
return v.flags&(valueFlagExported|valueFlagIndirect) == valueFlagExported|valueFlagIndirect
|
return v.flags&(valueFlagExported|valueFlagIndirect|valueFlagRO) == valueFlagExported|valueFlagIndirect
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) Bool() bool {
|
func (v Value) Bool() bool {
|
||||||
|
@ -668,11 +682,22 @@ func (v Value) Field(i int) Value {
|
||||||
panic(&ValueError{Method: "Field", Kind: v.Kind()})
|
panic(&ValueError{Method: "Field", Kind: v.Kind()})
|
||||||
}
|
}
|
||||||
structField := v.typecode.rawField(i)
|
structField := v.typecode.rawField(i)
|
||||||
flags := v.flags
|
|
||||||
|
// Copy flags but clear EmbedRO; we're not an embedded field anymore
|
||||||
|
flags := v.flags & ^valueFlagEmbedRO
|
||||||
|
|
||||||
if structField.PkgPath != "" {
|
if structField.PkgPath != "" {
|
||||||
// The fact that PkgPath is present means that this field is not
|
// No PkgPath => not exported.
|
||||||
// exported.
|
// Clear exported flag even if the parent was exported.
|
||||||
flags &^= valueFlagExported
|
flags &^= valueFlagExported
|
||||||
|
|
||||||
|
// Update the RO flag
|
||||||
|
if structField.Anonymous {
|
||||||
|
// Embedded field
|
||||||
|
flags |= valueFlagEmbedRO
|
||||||
|
} else {
|
||||||
|
flags |= valueFlagStickyRO
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Parent field may not have been exported but we are
|
// Parent field may not have been exported but we are
|
||||||
flags |= valueFlagExported
|
flags |= valueFlagExported
|
||||||
|
@ -1437,7 +1462,7 @@ func Zero(typ Type) Value {
|
||||||
return Value{
|
return Value{
|
||||||
typecode: typ.(*rawType),
|
typecode: typ.(*rawType),
|
||||||
value: nil,
|
value: nil,
|
||||||
flags: valueFlagExported,
|
flags: valueFlagExported | valueFlagRO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,14 +1470,14 @@ func Zero(typ Type) Value {
|
||||||
return Value{
|
return Value{
|
||||||
typecode: typ.(*rawType),
|
typecode: typ.(*rawType),
|
||||||
value: unsafe.Pointer(zerobuffer),
|
value: unsafe.Pointer(zerobuffer),
|
||||||
flags: valueFlagExported,
|
flags: valueFlagExported | valueFlagRO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Value{
|
return Value{
|
||||||
typecode: typ.(*rawType),
|
typecode: typ.(*rawType),
|
||||||
value: alloc(typ.Size(), nil),
|
value: alloc(typ.Size(), nil),
|
||||||
flags: valueFlagExported,
|
flags: valueFlagExported | valueFlagRO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1546,6 +1571,10 @@ func Copy(dst, src Value) int {
|
||||||
dstbuf, dstlen := buflen(dst)
|
dstbuf, dstlen := buflen(dst)
|
||||||
srcbuf, srclen := buflen(src)
|
srcbuf, srclen := buflen(src)
|
||||||
|
|
||||||
|
if srclen > 0 {
|
||||||
|
dst.checkRO()
|
||||||
|
}
|
||||||
|
|
||||||
return sliceCopy(dstbuf, srcbuf, dstlen, srclen, dst.typecode.elem().Size())
|
return sliceCopy(dstbuf, srcbuf, dstlen, srclen, dst.typecode.elem().Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче