Введение
Интерфейс golang очень широко используется, почти каждый пакет будет использовать этот интерфейс, а пакет fmt является одним из наиболее часто используемых. В реальной разработке необходимо определить стандартный вывод структуры с помощью String(), стандартный вывод ошибок Error(), форматированный вывод Format() и специальный GoString(). Далее описывается использование интерфейса, сценарии использования и замечания.
String()
type TestString struct {}
func (t TestString) String() string {
return "我是String"
}
func main() {
fmt.Println(TestString{})
}
我是String
Он относительно прост в использовании, если его структураString() string
можно вывести.
fmt
Сумка определит, есть лиfmt.Stringer
интерфейс, а затем вызов.
Обычно используется для вывода структур по умолчанию, например:
type Student struct {
number int
realname string
age int
}
func main() {
stu := &Student{
number: 1,
realname: "王小明",
age: 18,
}
fmt.Println(stu)
}
&{1 王小明 18}
Измените его на:
type Student struct {
number int
realname string
age int
}
func (t *Student) String() string {
return fmt.Sprintf("学号: %d\n真实姓名: %s\n年龄: %d\n", t.number, t.realname, t.age)
}
func main() {
stu := &Student{
number: 1,
realname: "王小明",
age: 18,
}
fmt.Println(stu)
}
学号: 1
真实姓名: 王小明
年龄: 18
Почувствуйте себя выше в мгновение ока!!
Error
type TestError struct {}
func (t TestError) Error() string {
return "我是Error"
}
func main() {
fmt.Println(TestString{})
}
我是Error
На самом деле, как использоватьString()
То же самое, но реализации нельзя заменять друг другом при разработке кода.
Наиболее распространенное использование - автономная упаковка.type XXXError struct{}
, в конце статьи я постараюсь разобраться, почему он используется именно так.
Format
type TestFormat struct {}
func (t TestFormat) Format(s fmt.State, c rune) {
switch c {
case 'c':
switch {
case s.Flag('+'):
fmt.Printf("我是+c\n")
default:
fmt.Fprint(s, "我是c\n")
}
default:
fmt.Print("我是Format")
}
}
func main() {
t := TestFormat{}
fmt.Println(t)
fmt.Printf("%c\n", t)
fmt.Printf("%+c\n", t)
fmt.Printf("%s\n", t)
}
我是Format
我是c
我是+c
我是Format
fmt.Println
Интерфейс Format также будет вызываться, поэтомуString()
Format()
не может находиться в одной структуре.
Обычно используется сError()
Аналогично, вы можете обратиться кgithub.com/pkg/errorsвнутреннийstack.go
изfunc (f Frame) Format(s fmt.State, verb rune)
GoString
type TestGoString struct {}
func (t TestGoString) GoString() string {
return "我是GoString"
}
func main() {
t := TestGoString{}
fmt.Println(TestGoString{})
fmt.Printf("%s %#v\n", t, t)
}
{}
{} 我是GoString
Как показано вышеfmt.Println
Метод GoString не вызывается, только форматированием%#
+ пометить вывод.
В случае отсутствия реализации интерфейса он обычно используется для вывода соответствующего значения по умолчанию, как показано ниже:
func main() {
var i uint = 18
// 输出十六进制
fmt.Printf("%x\n", i)
fmt.Printf("%#x\n", i)
}
12
0x12
Меры предосторожности
fmt/print.go
изpp.handleMethods(verb rune) (handled bool)
func (p *pp) handleMethods(verb rune) (handled bool) {
...
// 判断Formatter
if formatter, ok := p.arg.(Formatter); ok {
...
formatter.Format(p, verb)
return
}
// 判断是否含有#标识符
if p.fmt.sharpV {
// 判断GoStriner
if stringer, ok := p.arg.(GoStringer); ok {
...
p.fmt.fmtS(stringer.GoString())
return
}
} else {
switch verb {
case 'v', 's', 'x', 'X', 'q':
switch v := p.arg.(type) {
// 符合error接口
case error:
...
p.fmtString(v.Error(), verb)
return
// 符合Stringer接口
case Stringer:
...
p.fmtString(v.String(), verb)
return
}
}
}
return false
}
Формат -> (#) GoString -> ((v, s, x, X, q) Ошибка -> Строка) Все четыре интерфейса исходного кода управляются вызовом метода handlerMethods, они не независимы друг от друга и вызываются в соответствии с порядком приоритета. Поэтому дизайн интерфейса должен быть инкапсулирован как можно более независимо, чтобы избежать путаницы.
резюме
String()
Для стандартного вывода в структуры и т.д.
Error()
Метод инкапсуляции ошибок, вы можете изменить некоторые ошибки и выгрузить их в лог-систему или распечатать стек.
Format()
заString()
Расширенное использование для нескольких типов или форматов.
GoString()
Часто используется для относительных значений.
Добро пожаловать к великим богам, чтобы общаться и направлять!