博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang小程序试验(五)
阅读量:7008 次
发布时间:2019-06-28

本文共 3822 字,大约阅读时间需要 12 分钟。

  hot3.png

1. golang的指针

可以将unsafe.Pointer转换成uintptr,然后变相做指针运算

package mainimport "fmt"import "unsafe"type User struct {	Id   int	Name string}func main() {	u := &User{1, "tom"}	var up uintptr = uintptr(unsafe.Pointer(u)) + unsafe.Offsetof(u.Name)	var name *string = (*string)(unsafe.Pointer(up))	fmt.Println(*name)}

2. package io

实现了io.Reader或io.Writer接口的类型(导出的类型):

  • os.File 同时实现了io.Reader和io.Writer
  • strings.Reader 实现了io.Reader
  • bufio.Reader/Writer 分别实现了io.Reader和io.Writer
  • bytes.Buffer 同时实现了io.Reader和io.Writer
  • bytes.Reader 实现了io.Reader
  • compress/gzip.Reader/Writer 分别实现了io.Reader和io.Writer
  • crypto/cipher.StreamReader/StreamWriter 分别实现了io.Reader和io.Writer
  • crypto/tls.Conn 同时实现了io.Reader和io.Writer
  • encoding/csv.Reader/Writer 分别实现了io.Reader和io.Writer
  • mime/multipart.Part 实现了io.Reader
以上类型中,常用的类型有:os.File、strings.Reader、bufio.Reader/Writer、bytes.Buffer、bytes.Reader

WriteAt()方法简单示例:

file, err := os.Create("writeAt.txt")if err != nil {    panic(err)}defer file.Close()file.WriteString("Golang中文社区——这里是多余的")n, err := file.WriteAt([]byte("Go语言学习园地"), 24)if err != nil {    panic(err)}fmt.Println(n)

file.WriteString("Golang中文社区——这里是多余的") 往文件中写入Golang中文社区——这里是多余的;之后file.WriteAt([]byte("Go语言学习园地"), 24) 在文件流的offset=24处写入Go语言学习园地(会覆盖该位置的内容)。

ReadFrom()方法简单示例:

file, err := os.Open("writeAt.txt")if err != nil {    panic(err)}defer file.Close()writer := bufio.NewWriter(os.Stdout)writer.ReadFrom(file)writer.Flush()
WriteTo()方法示例:
reader := bytes.NewReader([]byte("Go语言学习园地"))reader.WriteTo(os.Stdout)
Seek()方法示例:
reader := strings.NewReader("Go语言学习园地")reader.Seek(-6, os.SEEK_END)r, _, _ := reader.ReadRune()fmt.Printf("%c\n", r)

在标准库中,有如下类型实现了io.ByteReader或io.ByteWriter:

  • bufio.Reader/Writer 分别实现了io.ByteReader和io.ByteWriter
  • bytes.Buffer 同时实现了io.ByteReader和io.ByteWriter
  • bytes.Reader 实现了io.ByteReader
  • strings.Reader 实现了io.ByteReader

接下来的示例中,我们通过bytes.Buffer来一次读取或写入一个字节(主要代码):

var ch bytefmt.Scanf("%c\n", &ch)buffer := new(bytes.Buffer)err := buffer.WriteByte(ch)if err == nil {    fmt.Println("写入一个字节成功!准备读取该字节……")    newCh, _ := buffer.ReadByte()    fmt.Printf("读取的字节:%c\n", newCh)} else {    fmt.Println("写入错误")}
Pipe()方法和PipeReader、PipeWriter结构的示例:
func main() {    Pipe()}func Pipe() {    pipeReader, pipeWriter := io.Pipe()    go PipeWrite(pipeWriter)    go PipeRead(pipeReader)    time.Sleep(1e7)}func PipeWrite(pipeWriter *io.PipeWriter) {    var (        i   = 0        err error        n int    )    data := []byte("Go语言学习园地")    for _, err = pipeWriter.Write(data); err == nil; n, err = pipeWriter.Write(data) {        i++        if i == 3 {            pipeWriter.CloseWithError(errors.New("输出3次后结束"))        }    }    fmt.Println("close 后输出的字节数:", n, " error:",  err)}func PipeRead(pipeReader *io.PipeReader) {    var (        err error        n   int    )    data := make([]byte, 1024)    for n, err = pipeReader.Read(data); err == nil; n, err = pipeReader.Read(data) {        fmt.Printf("%s\n", data[:n])    }    fmt.Println("writer 端 closewitherror后:", err)}
Copy()方法示例:
package mainimport (    "fmt"    "io"    "os")func main() {    io.Copy(os.Stdout, strings.NewReader("Go语言学习园地"))    io.Copy(os.Stdout, os.Stdin)    fmt.Println("Got EOF -- bye")}

3. 程序结构

假设有一个服务的大致实现是这样的:

type Service struct {wg sync.WaitGroup}func (p *Service) Start() {p.wg.Add(1)go p.run()}func (p *Service) Close() {// ...p.wg.Wait()}func (p *Service) run() {defer p.wg.Done()// ....}
其中run()是服务的主要逻辑实现。这样写法的问题是wg的Add和Done函数调用分离了,容易导致在以后的代码维护中不小心就导致Add和Done的调用不匹配从而Wait执行的结果不符合预期。从代码组织的方式上来说,应该把功能相关的代码尽可能地放在一起。

type Service struct {wg sync.WaitGroup}func (p *Service) Start() {p.wg.Add(1)go func() {p.run()p.wg.Done()}()}func (p *Service) Close() {// ...p.wg.Wait()}func (p *Service) run() {// ....}
这个其实也算常识了,写过些代码的人可能都知道。但是在实际的代码中,我们往往还会发现类似这样的一些不好的写法。因此,对于这些惯用法(或者升级为代码规范),我觉得更重要的不是了解知道,而是执行和遵守。 

转载于:https://my.oschina.net/renguijiayi/blog/186994

你可能感兴趣的文章
完成端口(CompletionPort)详解 - 手把手教你玩转网络编程系列之三
查看>>
JSP Struts之HTML标签库详解
查看>>
Hp服务器 raid 磁盘故障数据库数据恢复解决方案
查看>>
运维角度浅谈MySQL数据库优化
查看>>
【Spark亚太研究院系-构建Spark集群-配置Hadoop单机模式并运行Wordcount(2)
查看>>
Java通过POI为Excel添加数据验证
查看>>
修改vim的配色方案
查看>>
程矢Axure夜话:程序员眼中的原型设计视频教程之书到用时方恨少
查看>>
网站降权怎么办
查看>>
esxi 4.x升级至5.0
查看>>
Hibernate中save、persist和saveOrUpdate这三个方法的区别
查看>>
c++去掉字符串中连续的空格,只保留一个
查看>>
按钮动画学习2
查看>>
我的友情链接
查看>>
纯靠内链提权重
查看>>
linux因环境变量修改错误,造成命令查找不到,且无法登陆系统解决办法
查看>>
元芳,你怎么看,网络为何会如此流行!
查看>>
计算机运行命令全集
查看>>
Android项目之旅三 简易Mp3播放器从获取服务器端Mp3信息
查看>>
将一个数组中的奇元素全部移到数组的前半部分,即将奇偶元素分开
查看>>