Muxx


  • 首页

  • 归档

  • 标签

  • 关于

  • 搜索

go 环境配置

发表于 2020-07-05

环境问题

1.go test: can’t load package: package … is not in GOROOT

GO111MODULE配置不当导致的问题。

首先我们了解下GO111MODULE产生的背景

首先,让我们谈谈 GOPATH。当 Go 在 2009 年首次推出时,它并没有随包管理器一起提供。取而代之的是 go get,通过使用它们的导入路径来获取所有源并将其存储在 $ GOPATH / src 中。没有版本控制并且『master』分支表示该软件包的稳定版本。

Go 1.11 引入了 Go 模块 (以前称为 vgo- 版本为 Go)。 Go Modules 不使用 GOPATH 存储每个软件包的单个 git checkout,而是存储带有 go.mod 标记版本的标记版本,并跟踪每个软件包的版本。

GO111MODULE是一个环境变量,通过它来控制『GOPATH 行为』与『Go Modules 行为』

  • GO111MODULE = on,强制使用Go模块,需要go.mod正常工作(即使处于GOPATH下)。
  • GO111MODULE = off,强制使用GOPATH,从$GOPATH/src下获取所有源
  • 在 Go 1.13 下, GO111MODULE 的默认行为 (auto) 改变了:
    • 当存在 go.mod 文件时或处于 GOPATH 外, 其行为均会等同于于 GO111MODULE=on。这意味着在 Go 1.13 下你可以将所有的代码仓库均存储在 GOPATH 下。
    • 当处于 GOPATH 内且没有 go.mod 文件存在时其行为会等同于 GO111MODULE=off。

go深坑之interface与nil

发表于 2020-06-26

问题演示

这里演示实际项目中可能出现的场景,IRedisCon是接口,RedisCon是接口的实现,代码中通过getRedisCon()方法获取redis连接对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 接口类型
type IRedisCon interface {
}
// IRedisCon的具体实现
type RedisCon struct {
}
//获取RedisCon类型数据
func getRedisCon() *RedisCon {
return nil
}
func main() {
var redisCon IRedisCon
redisCon = getRedisCon()
fmt.Println(redisCon == nil)
}
阅读全文 »

go rune与byte

发表于 2020-06-05

rune 与 byte类型转换时是否需要重新分配内存呢?
首先了解下两者的定义

  • rune是一个int32的别名,通常用来处理unicode或utf8字符
  • byte等同于int8,常用来处理字符
1
2
3
4
5
6
7
8
9
10
runePresent:=[]rune("你")
fmt.Printf("%x %#U %d",runePresent,runePresent,len(runePresent))
fmt.Println()
bytePresent:=[]byte("你")
fmt.Printf("%x %#U %d",bytePresent,bytePresent,len(bytePresent))
fmt.Println()
//输出
[4f60] [U+4F60 '你'] 1
e4bda0 [U+00E4 'ä' U+00BD '½' U+00A0] 3

可以看到rune与byte的存储不同的,所以rune与byte相互想换必然伴随着内存分配

如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。

需要注意的是,Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一

unicode=>utf8流程

首先找到字符对应的unicode编码,然后根据utf8存储规则进行转换

utf8与unicode

go slice 扩容分析

发表于 2020-05-27

以此为例进行讲解

1
2
3
s := []int64{1, 2}
ns := append(s, []int64{1, 2, 3}...)
fmt.Println(cap(ns))

cap 扩容最小元素数
newcap 扩容后实际元素数

阅读全文 »

Postman实战

发表于 2020-05-18

环境

通常用用于访问指定环境的服务,比如测试环境、分级环境、线上环境

阅读全文 »

Go defer的坑

发表于 2020-04-30

常见问题

defer常见用法

阅读全文 »

Go标准库之io

发表于 2020-04-27

常量

1
2
3
4
io.EOF 根据reader接口说明,在n>0且数据被读完的情况下,当次返回的error有可能是EOF也有可能是nil
SeekStart = 0 // seek relative to the origin of the file
SeekCurrent = 1 // seek relative to the current offset
SeekEnd = 2 // seek relative to the end
阅读全文 »

Go标准库之strings

发表于 2020-04-27

数据结构

strings.Builder

strings.Builder结构体用于构建字符串。
与string值相比优势主要体现在字符串拼接方面,string拼接的结果是生成新的string,需要把原字符串拷贝到新的string中;Builder底层存在[]byte,按需扩容,不必每次都进行拷贝

对于非空的strings.Builder复制会引发panic

1
2
3
4
5
实现接口
builder := new(strings.Builder)
_ = interface{}(builder).(io.Writer)
_ = interface{}(builder).(io.ByteWriter)
_ = interface{}(builder).(fmt.Stringer)

strings.Reader

strings.Reader结构体用于读取字符串
Reader的优势是维护了一个已读计数器,知道下一次读的位置,读取速度更快

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Reader.Read
Reader.ReadAt
Reader.ReadByte
Reader.ReadRune
Reader.Size
Reader.Len
Reader.UnreadByte
Reader.UnreadRune
Reader.WriteTo
实现接口
reader := strings.NewReader("")
_ = interface{}(reader).(io.Reader)
_ = interface{}(reader).(io.ReaderAt)
_ = interface{}(reader).(io.ByteReader)
_ = interface{}(reader).(io.RuneReader)
_ = interface{}(reader).(io.Seeker)
_ = interface{}(reader).(io.ByteScanner)
_ = interface{}(reader).(io.RuneScanner)
_ = interface{}(reader).(io.WriterTo)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//strings.Builder
var s strings.Builder
s.WriteString("hello")
s.WriteString(" ")
s.WriteString("world")
fmt.Printf("%s", s.String())
s2 := s
fmt.Printf("%s", s2.String())
//s2.WriteString("trigger panic") 复制触发panic
//strings.Reader
reader := strings.NewReader("hello world")
buf := make([]byte, 20)
n, err := reader.Read(buf)
if err != nil {
fmt.Println(err)
}
fmt.Printf("read size %d", n)

函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
字符串比较
strings.Compare 比==更快
stirngs.EqualFold 以utf8编码解析且无视大小写的条件下比较字符串
//包含
strings.Contains
strings.ContainsAny s包含sub中任何字符,返回true
stirngs.ContainsRune unicode字符是否在s中
strings.Count sub在s中的出现次数
分割/组装
strings.Fields 以空格分隔字符串,返回切片
strings.FieldsFunc
strings.Join 组合切片,返回字符串
strings.Split 以字符串分割字符串,返回切片
//前缀 后缀
strings.HasPrefix 拥有前缀
strings.HasSuffix 拥有后缀
//查找
strings.Index 查找子串sub所在位置
strings.IndexByte 查找字符在s中所在位置
strings.IndexRune 查找unicode字符在s中所在位置
strings.LastIndex 查找子串sub在s中最后出现位置
strings.LastIndexByte
strings.LastIndexAny 查找子串任意字符在s中最后出现位置
strings.LastIndexFunc 查找子串符合条件
123…29
Mu

Mu

230 日志
53 标签
© 2021 Mu
由 Hexo 强力驱动
主题 - NexT.Pisces