Go   发布时间:2022-04-09  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了golang小程序试验(五)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

1. golang的指针

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

package main

import "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 byte
fmt.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 main

import (
    "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() {
// ....
}
这个其实也算常识了,写过些代码的人可能都知道。但是在实际的代码中,我们往往还会发现类似这样的一些不好的写法。因此,对于这些惯用法(或者升级代码规范),我觉得更重要的不是了解知道,而是执行和遵守。

大佬总结

以上是大佬教程为你收集整理的golang小程序试验(五)全部内容,希望文章能够帮你解决golang小程序试验(五)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。