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