内容简介:golang的接口使用非常广泛,几乎每一个包都会用到接口,fmt包的使用率最多之一。在实际开发中,要定义结构体的标准输出用String(),定义标准错误输出Error(),定义格式化输出Format(),还有比较特殊的GoString()。接下来描述接口的使用方式,使用场景,还有注意的地方。使用起来比较简单,只要结构体里面有
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 } 复制代码
Format -> (#)GoString -> ((v,s,x,X,q)Error -> String) 源码四个接口都在handlerMethods方法调用控制,都不是互相独立,根据优先顺序调用。所以接口的设计,尽可能独立封装,避免混淆。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- delphi – 如何检查接口对象是否实现了另一个接口?
- SpringBoot2 API接口签名实现(接口参数防篡改)
- 接口与实现分离
- 判断Golang接口是否实现
- Python实现数据驱动接口测试
- Spring应用--实现InitializingBean接口
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Where Wizards Stay Up Late
Katie Hafner / Simon & Schuster / 1998-1-21 / USD 16.00
Twenty five years ago, it didn't exist. Today, twenty million people worldwide are surfing the Net. "Where Wizards Stay Up Late" is the exciting story of the pioneers responsible for creating the most......一起来看看 《Where Wizards Stay Up Late》 这本书的介绍吧!