英文:
How does Go unmarshall a string into a wrapped atomc int?
问题
Uber的日志记录库Zap有一个Config
结构体,其中日志级别定义如下:
type Config struct {
Level AtomicLevel `json:"level" yaml:"level"`
}
其中类型AtomicLevel
是一个包装了Go的atomic.Int32
的结构体:
type AtomicLevel struct {
l *atomic.Int32
}
在这个设置中,Go的json.Unmarshal
如何成功地将一个字符串(比如"debug")解组成正确的原子整数值,如下面的示例所示?
package main
import (
"encoding/json"
"go.uber.org/zap"
)
func main() {
// 对于某些用户来说,NewProduction、NewDevelopment和NewExample构造函数提供的预设可能不合适。
// 对于大多数用户来说,捆绑的Config结构体提供了灵活性和便利性的正确平衡。(对于更复杂的需求,请参阅AdvancedConfiguration示例。)
//
// 有关所有可用选项,请参阅Config和zapcore.EncoderConfig的文档。
rawJSON := []byte(`{
"level": "debug",
"encoding": "json",
}`)
var cfg zap.Config
if err := json.Unmarshal(rawJSON, &cfg); err != nil {
panic(err)
}
logger, err := cfg.Build()
if err != nil {
panic(err)
}
defer logger.Sync()
logger.Info("logger construction succeeded")
}
英文:
Uber's logging library Zap has a Config
struct, in which the log level is defined as follows:
type Config struct {
Level AtomicLevel `json:"level" yaml:"level"`
}
Where the type AtomicLevel
is a struct
that wraps Go's atomic.Int32
:
type AtomicLevel struct {
l *atomic.Int32
}
With this setup, how can Go's json.Unmarshall
successfully unmarshalls a string
, say, "debug" into the correct atomic int value, as the following example illustrates?
package main
import (
"encoding/json"
"go.uber.org/zap"
)
func main() {
// For some users, the presets offered by the NewProduction, NewDevelopment,
// and NewExample constructors won't be appropriate. For most of those
// users, the bundled Config struct offers the right balance of flexibility
// and convenience. (For more complex needs, see the AdvancedConfiguration
// example.)
//
// See the documentation for Config and zapcore.EncoderConfig for all the
// available options.
rawJSON := []byte(`{
"level": "debug",
"encoding": "json",
}`)
var cfg zap.Config
if err := json.Unmarshal(rawJSON, &cfg); err != nil {
panic(err)
}
logger, err := cfg.Build()
if err != nil {
panic(err)
}
defer logger.Sync()
logger.Info("logger construction succeeded")
}
答案1
得分: 2
AtomicLevel具有一个UnmarshalText方法,这意味着它实现了encoding.TextUnmarshaler接口。当JSON解码器看到一个JSON字符串并且目标类型实现了TextUnmarshaler接口时,它会调用其UnmarshalText方法将字符串转换为适当的值(除非该类型实现了json.Unmarshaler
,在这种情况下,它优先)。AtomicLevel没有实现json.Unmarshaler
。
英文:
AtomicLevel has an UnmarshalText method, which means it implements the encoding.TextUnmarshaler interface. When the JSON decoder sees a JSON string and the destination is a type that implements TextUnmarshaler, its UnmarshalText method is called to convert the string into an appropriate value (unless the type implements json.Unmarshaler
, in which case that takes precedence. AtomicLevel doesn't.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论