正如我们从ByteSize上看到的,任何命名类型(指针和接口除外)都可以定义方法(method);接收者(receiver)不必为一个结构体。
在上面有关切片的讨论中,我们编写了一个Append函数。我们还可以将其定义成切片的方法。为此,我们首先声明一个用于绑定该方法的命名类型,然后将方法的接收者作为该类型的值。
```
type ByteSlice []byte
func (slice ByteSlice) Append(data []byte) []byte {
// Body exactly the same as above
}
```
这样还是需要方法返回更新后的切片。我们可以通过重新定义方法,接受一个ByteSlice的指针作为它的接收者,来消除这样笨拙的方式。这样,方法就可以改写调用者的切片。
```
func (p *ByteSlice) Append(data []byte) {
slice := *p
// Body as above, without the return.
*p = slice
}
```
实际上,我们可以做的更好。如果我们将函数修改成标准Write方法的样子,像这样,
```
func (p *ByteSlice) Write(data []byte) (n int, err error) {
slice := *p
// Again as above.
*p = slice
return len(data), nil
}
```
那么类型*ByteSlice就会满足标准接口io.Writer,这样就很方便。例如,我们可以打印到该类型的变量中。
```
var b ByteSlice
fmt.Fprintf(&b, "This hour has %d days\n", 7)
```
我们传递ByteSlice的地址,是因为只有*ByteSlice才满足io.Writer。关于接收者对指针和值的规则是这样的,值方法可以在指针和值上进行调用,而指针方法只能在指针上调用。这是因为指针方法可以修改接收者;使用拷贝的值来调用它们,将会导致那些修改会被丢弃。
- 命令行库cobra
- 用户路径检测go-homedir
- 配置解决方案viper(cobra配置用)
- 高效结构化日志库zap
- RPC框架grpc
- mongdb操作mgo
- ORM库xorm
- GRPCrest接口grpcgateway
- 使用gogoproto时grpcgateway的protobuf和json转换方法
- sync.Map
- zmq
- gogoproto
- go类型转换和类型断言
- go select用法详解以及定时器
- go并发资源竞争
- 官方命令行库flag
- 配置文件解析器 robig/config
- interface {} 接口
- goroutine && channel
- go 命名
- 类型switch
- 数据
- 初始化
- 指针方法 && 值方法
- 内嵌
- mqtt go实现
- grpc middleware