英文:
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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论